`include "chunjun_define.sv" 
`include "chunjun_lib_define.sv" 

//================================================================================================
// File Name   : tcu/chunjun_tcu.sv
// Create Time : Mon Sep  9 10:51:14 2024
// Description : Tightly Coupled memory Unit(TCU). Receive instruction fetch req from ICU, load and
//               store req from LSU, SBU and BUS, vector load and store req from VPU. 
//               Including ITCM, DTCM, and VTCM 
//================================================================================================

//pcu_csr_meictl
//TCU只关心以下位域：
//[0] :   injection enable
//[4:1]: inject_dest
//         4'b0000: ICache tag
//         4'b0001: ICache data
//         4'b0100: DCache tag
//         4'b0101: DCache data
//         4'b1000: ITCM
//         4'b1010: DTCM0
//         4'b1011: DTCM1
//         4'b1100: VTCM
//[8:5]: bank
//         ITCM：                默认一个bank，不可配置数量，bank width 64-bit
//         DTCM0，DTCM1：默认一个bank，不可配置数量，bank width 64-bit
//         VTCM：               默认2个bank，可配置2/4/8个bank，bank width 32-bit。
//                                   其中even bank由MSEIBL指示，odd bank由MSEIBH指示
//                                   
 

module chunjun_tcu (

input  logic                                                           clk                        ,   //时钟信号
input  logic                                                           rst_n                      ,   //复位信号
output logic                                                           tcu_idle                   ,   // set when TCU is idle, TCU没有任何pending的请求

input  logic [11:0]                                                    itcm_global_base_addr      ,   //ITCM全局基址
input  logic [11:0]                                                    dtcm0_global_base_addr     ,   //DTCM0(数据TCM0)的全局基址
`ifdef CHUNJUN_SUPPORT_DTCM1  
input  logic [11:0]                                                    dtcm1_global_base_addr     ,   //DTCM1(数据TCM1)的全局基址
`endif // CHUNJUN_SUPPORT_DTCM1
`ifdef CHUNJUN_SUPPORT_VTCM  
input  logic [11:0]                                                    vtcm_global_base_addr      ,   //VTCM(向量TCM)的全局基址
`endif // CHUNJUN_SUPPORT_VTCM

// pcu <-> tcu
input  logic [31:0]                                                    pcu_csr_msyscfg            ,   // CSR: msyscfg,TCU只关心1-bit, [3]: Enable ECC Check, 1'b0: Disable ECC, 1'b1: Enable ECC 
input  logic [31:0]                                                    pcu_csr_meictl             ,   // CSR: [0] = csr_inject_en, [4:1] memory select, [8:5] bank select
input  logic [31:0]                                                    pcu_csr_meibmap            ,   // CSR: Inject bitmap low（64-bit的低32bit / even bank）
input  logic [31:0]                                                    pcu_csr_meibmaph           ,   // CSR: Inject bitmap high（64-bit的高32bit / odd bank）
 
/////////////////////////////////
// ICU <-> TCU
/////////////////////////////////

input  logic                                                           icu_tcu_req_vld_m1         ,  //ICU访问TCU读请求的valid指示信号
output logic                                                           tcu_icu_req_rdy_m1         ,  //TCU接收ICU读请求的ready指示信号
input  logic [20-1:0]                                 icu_tcu_req_addr_m1        ,                   //ICU访问TCU读请求的地址。每个内核的各个L1TCM分配了1MB的memory map space。不支持分对齐地址访问
input  logic [2:0]                                                     icu_tcu_req_route_m1       ,  //3'b001：访问ITCM；3'b010：访问DTCM0；3'b100：访问DTCM1；
input  logic [$clog2(4)-1:0]                                  icu_tcu_req_id_m1          ,  //ICU访问TCU读请求的ID， ICU发出的请求ID取决于ROB entry数量（entry数量默认为4）
 
input  logic                                                           icu_tcu_flush_m2           ,  //ICU在M2 stage发送给TCU的Flush信号, 1'b1: TCU需要flush掉在途的来自ICU的全部请求，（M2当拍的响应仍然返回）, Flush当拍的请求视作有效请求
input  logic                                                           icu_tcu_cancel_m2          ,  //ICU在M2 stage发送给TCU的Cancel信号, 1'b1: TCU需要flush掉M2当拍的请求，（M2当拍的响应不返回）,cancel当拍的请求视作有效请求
 
output logic                                                           tcu_icu_rsp_vld_m2         ,  //TCU向ICU发送m2 stage读响应的valid指示信号
input  logic                                                           icu_tcu_rsp_rdy_m2         ,  //ICU接收TCU读响应的ready指示信号
output logic [63:0]                                                    tcu_icu_rsp_data_m2        ,  //TCU向ICU发送m2 stage读响应的数据, (未经过ECC纠错的原始读数据)
output logic [$clog2(4)-1:0]                                  tcu_icu_rsp_id_m2          ,           //TCU向ICU发送m2 stage读响应的ID
output logic                                                           tcu_icu_rsp_vld_m3         ,  //TCU向ICU发送m3 stage读响应的valid指示信号
output logic                                                           tcu_icu_rsp_raserr_m3      ,  //TCU向ICU发送读响应的错误指示信号。* 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error * 当配置不使能ECC时，不会返回error
output logic                                                           tcu_icu_rsp_replay_m3      ,  //TCU向ICU发送replay的指示信号, 当配置使能ECC，并检测到了1-bit error，该信号置1。ICU会根据replay信号重新发送该请求。
output logic [$clog2(4)-1:0]                                  tcu_icu_rsp_id_m3          ,  //TCU向ICU发送m3 stage读响应的ID    

/////////////////////////////////
// LSU <-> TCU
/////////////////////////////////

input  logic [1:0]                                                     lsu_tcu_ld_req_valid_m1    ,  //发送给TCU的Load请求有效信号, 2bit 分别表示两路load口，下同不赘述
output logic [1:0]                                                     tcu_lsu_ld_req_ready_m1    ,  //TCU接收load请求ready信号
//LSU访问ITCM/DTCM：根据addr[2]来判断load memory的高32-bit还是低32-bit
//LSU访问VTCM：根据addr[2+:($clog2(VBANK_N)-1)]判断访问哪一个VTCM bank
input  logic [1:0][20-1:0]                            lsu_tcu_ld_req_addr_m1     ,  //发送给TCU的Load请求地址（默认4B对齐，TCU忽略低2bit0）,每个内核的各个L1TCM分配了1MB的memory map space。(不支持非对齐地址访问)
input  logic [1:0][3:0]                                                lsu_tcu_ld_req_route_m1    , //4'b0001：访问ITCM；4'b0010：访问DTCM0；4'b0100：访问DTCM1；4'b1000：访问VTCM
input  logic [1:0][1:0]                                                lsu_tcu_ld_req_size_m1     ,  //发送给TCU的Load请求大小  0 - Byte 1 - Half Word 2 - Word
input  logic [1:0][($clog2(6) + 1)-1:0]                               lsu_tcu_ld_req_lsqid_m1    ,   //发送给TCU的Load请求id, 最高位为绕回位
 
input  logic [1:0]                                                     lsu_tcu_ld_req_cancel_m2   ,   // M2 Stage发送给TCU的取消load请求指示信号, 同拍的M2响应不返回。
input  logic                                                           lsu_tcu_flush_valid        ,   // LSU flush有效信号，为1指示lsu要将flush id对应的TCU中的load及更年轻的load请求flush掉。Flush同拍的新发送的load请求不受flush影响。（同拍的M2响应不返回）
input  logic [($clog2(6) + 1)-1:0]                                    lsu_tcu_flush_lsqid        , //flush id

output logic [1:0]                                                     tcu_lsu_ld_rsp_valid_m2    ,  //TCU在M2 stage返回的Load数据响应有效信号
input  logic [1:0]                                                     lsu_tcu_ld_rsp_ready_m2    ,  //LSU接收TCU返回的读数据响应ready信号. 当前版本固接1，不反压TCU的读数据响应
output logic [1:0][31:0]                                               tcu_lsu_ld_rsp_data_m2     ,  //TCU返回的Load数据 (未经过ECC纠错的原始读数据)
output logic [1:0][($clog2(6) + 1)-1:0]                               tcu_lsu_ld_rsp_lsqid_m2    ,   //TCU返回的Load数据对应的请求id
output logic [1:0]                                                     tcu_lsu_ld_rsp_valid_m3    ,  //TCU在M3 stage返回的Load数据响应有效信号
output logic [1:0]                                                     tcu_lsu_ld_rsp_raserr_m3   ,   // TCU返回的Load响应出现RAS错误指示（不可恢复的ECC错误）* 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error  * 当配置不使能ECC时，不会返回error
output logic [1:0]                                                     tcu_lsu_ld_rsp_replay_m3   ,   //TCU向LSU发送replay的指示信号. 当配置使能ECC，并检测到了1-bit error，该信号置1。 .LSU会根据replay信号重新发送该请求。
output logic [1:0][($clog2(6) + 1)-1:0]                               tcu_lsu_ld_rsp_lsqid_m3    ,    //TCU向LSU发送replay的id

/////////////////////////////////
// SBU <-> TCU
/////////////////////////////////

input  logic                                                           sbu_tcu_req_vld            ,   //SBU访问TCU写请求的valid指示信号，默认ready可以依赖valid，valid不能依赖ready
output logic                                                           tcu_sbu_req_rdy            ,   //TCU接收SBU写请求的ready指示信号
//atomic请求根据sbu_tcu_req_addr[2]来判断对memory的高32-bit还是低32-bit进行操作。
input  logic [20-1:0]                                 sbu_tcu_req_addr           , //SBU访问TCU写请求的地址, 每个内核的各个L1TCM分配了1MB的memory map space。(不支持非对齐地址访问) (SBU不会发出hit TCM reserved空间地址的请求，也不会发出hit不支持atomic操作的TCM的atomic请求）
input  logic [3:0]                                                     sbu_tcu_req_route          ,   //每个内核的各个L1TCM分配了1MB的memory map space。
input  logic [63:0]                                                    sbu_tcu_req_wdata          ,   //SBU访问TCU写请求的数据
input  logic [7:0]                                                     sbu_tcu_req_wstrb          ,   //(不支持非对齐地址访问)
input  logic [5:0]                                                     sbu_tcu_req_atop           ,   // if atop != 6'b0, indicate it's an atomic req //(SBU不会发出hit TCM reserved空间地址的请求，也不会发出hit不支持atomic操作的TCM的atomic请求）
input  logic [$clog2(6)-1:0]                                sbu_tcu_req_id             , //SBU访问TCU写请求的id

output logic                                                           tcu_sbu_rsp_vld            ,  //TCU向SBU发送写响应的valid指示信号
input  logic                                                           sbu_tcu_rsp_rdy            ,  //SBU接收TCU返回的读数据响应ready信号. 当前版本固接1，不反压TCU的读数据响应
output logic [$clog2(6)-1:0]                                tcu_sbu_rsp_id             , //TCU向SBU发送写响应的ID指示信号
output logic                                                           tcu_sbu_rsp_raserr         ,   // 写响应ras error信号 * 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error * 当配置不使能ECC时，不会返回error


output logic                                                           tcu_sbu_atop_rvld          ,   //TCU向SBU发送atop原子操作的读响应valid指示信号. 约束：对于一笔atomic load请求，r response一定在b response返回之前或者当拍拉高
output logic [31:0]                                                    tcu_sbu_atop_rdata         ,   //TCU向SBU发送atop原子操作的读响应数据  (已经过ECC纠错的读数据)
output logic [$clog2(6)-1:0]                                tcu_sbu_atop_rid           , //TCU向SBU发送atop原子操作的读响应ID
output logic                                                           tcu_sbu_atop_raserr        ,   // TCU向SBU发送atomic操作的读响应的错误指示信号。 * 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error. SBU收到后不再感知rsp_raserr * 当配置不使能ECC时，不会返回error

/////////////////////////////////
// BMU <-> TCU
/////////////////////////////////

input  logic                                                           bmu_tcu_req_vld            ,   //Slave访问TCU读请求的valid指示信号
output logic                                                           tcu_bmu_req_rdy            ,   //TCU接收Slave读请求的ready指示信号
input  logic [20-1:0]                                 bmu_tcu_req_addr           ,                    //Slave访问TCU读请求的地址. 每个内核的各个L1TCM分配了1MB的memory map space。 (不支持非对齐地址访问) (BMU不会发出hit TCM reserved空间地址的请求)
input  logic [3:0]                                                     bmu_tcu_req_route          ,   //4'b0001：访问ITCM； 4'b0010：访问DTCM0； 4'b0100：访问DTCM1； 4'b1000:  访问VTCM；
input  logic [2:0]                                                     bmu_tcu_req_size           ,   //000: 1 byte 001: 2 byte 010: 4 byte 011: 8 byte 100: 16 byte. 当前实现TCU不看req_size，（load认为是full size，store以req_wstrb为准）

input  logic                                                           bmu_tcu_req_wr             ,   //Slave访问TCU请求的读写指示信号 . 1'b0: 读请求; 1'b1: 写请求
input  logic [`CHUNJUN_MBUS_DATA_W-1:0]                                bmu_tcu_req_wdata          ,   //Slave访问TCU请求的写数据
input  logic [(`CHUNJUN_MBUS_DATA_W/8)-1:0]                            bmu_tcu_req_wstrb          ,   //Slave访问TCU请求的byte选通指示信号。 每bit指示写数据的对应byte是否包含有效数据。
input  logic [(8 + 2 + 3)-1:0]                             bmu_tcu_req_id             ,   //Slave访问TCU读请求的ID指示信号

output logic                                                           tcu_bmu_rsp_vld            , //TCU向Slave发送响应的valid指示信号  (不支持反压)
output logic [`CHUNJUN_MBUS_DATA_W-1:0]                                tcu_bmu_rsp_data           , //TCU向Slave发送读响应的读数据 (已经过ECC纠错的读数据)
output logic [(8 + 2 + 3)-1:0]                             tcu_bmu_rsp_id             , //TCU向Slave发送响应的ID指示信号
output logic                                                           tcu_bmu_rsp_raserr         , //TCU向Slave发送读响应的成功指示信号  * 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error * 当配置不使能ECC时，不会返回error
 
// itcm <-> ram
output logic                                                           itcm_ram_cs                , //ITCM RAM片选信号
output logic                                                           itcm_ram_wr                , //ITCM RAM写指示信号。0 - 读请求；1 - 写请求。
output logic [`CHUNJUN_ITCM_RAM_ADDR_W-1:0]                            itcm_ram_addr              , //ITCM RAM地址指示信号。
output logic [`CHUNJUN_ITCM_RAM_DATA_W-1:0]                            itcm_ram_wen               , //ITCM RAM bit写选通信号。wen每一bit对应wdata的一个bit。
output logic [`CHUNJUN_ITCM_RAM_DATA_W-1:0]                            itcm_ram_wdata             , //ITCM RAM写数据。
input  logic [`CHUNJUN_ITCM_RAM_DATA_W-1:0]                            itcm_ram_rdata             , //ITCM RAM读数据。
 
// dtcm0 <-> ram
output logic                                                           dtcm0_ram_lo_cs            , //DTCM0 RAM low 32-bit bank片选信号
output logic                                                           dtcm0_ram_lo_wr            , //DTCM0 RAM low 32-bit bank写指示信号。0 - 读请求；1 - 写请求。
output logic [`CHUNJUN_DTCM0_RAM_ADDR_W-1:0]                           dtcm0_ram_lo_addr          , //DTCM0 RAM low 32-bit bank地址指示信号。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_lo_wen           , //DTCM0 RAM low 32-bit bank bit写选通信号。wen每一bit对应wdata的一个bit。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_lo_wdata         , //DTCM0 RAM low 32-bit bank写数据。
input  logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_lo_rdata         , //DTCM0 RAM low 32-bit bank读数据。
 
output logic                                                           dtcm0_ram_hi_cs            , //DTCM0 RAM high 32-bit bank片选信号
output logic                                                           dtcm0_ram_hi_wr            , //DTCM0 RAM high 32-bit bank写指示信号。0 - 读请求；1 - 写请求。
output logic [`CHUNJUN_DTCM0_RAM_ADDR_W-1:0]                           dtcm0_ram_hi_addr          , //DTCM0 RAM high 32-bit bank地址指示信号。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_hi_wen           , //DTCM0 RAM high 32-bit bank bit写选通信号。wen每一bit对应wdata的一个bit。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_hi_wdata         , //DTCM0 RAM high 32-bit bank写数据。
input  logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm0_ram_hi_rdata         , //DTCM0 RAM high 32-bit bank读数据。
 
// dtcm1 <-> ram
`ifdef CHUNJUN_SUPPORT_DTCM1
output logic                                                           dtcm1_ram_lo_cs            , //DTCM1 RAM low 32-bit bank片选信号
output logic                                                           dtcm1_ram_lo_wr            , //DTCM1 RAM low 32-bit bank写指示信号。0 - 读请求；1 - 写请求。
output logic [`CHUNJUN_DTCM1_RAM_ADDR_W-1:0]                           dtcm1_ram_lo_addr          , //DTCM1 RAM low 32-bit bank地址指示信号。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_lo_wen           , //DTCM1 RAM low 32-bit bank bit写选通信号。wen每一bit对应wdata的一个bit。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_lo_wdata         , //DTCM1 RAM low 32-bit bank写数据。
input  logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_lo_rdata         , //DTCM1 RAM low 32-bit bank读数据。

output logic                                                           dtcm1_ram_hi_cs            , //DTCM1 RAM high 32-bit bank片选信号
output logic                                                           dtcm1_ram_hi_wr            , //DTCM1 RAM high 32-bit bank写指示信号。0 - 读请求；1 - 写请求。
output logic [`CHUNJUN_DTCM1_RAM_ADDR_W-1:0]                           dtcm1_ram_hi_addr          , //DTCM1 RAM high 32-bit bank地址指示信号。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_hi_wen           , //DTCM1 RAM high 32-bit bank bit写选通信号。wen每一bit对应wdata的一个bit。
output logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_hi_wdata         , //DTCM1 RAM high 32-bit bank写数据。
input  logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                            dtcm1_ram_hi_rdata         , //DTCM1 RAM high 32-bit bank读数据。
`endif  // CHUNJUN_SUPPORT_DTCM1
 
`ifdef CHUNJUN_SUPPORT_V_EXT

/////////////////////////////////
// VPU <-> TCU
/////////////////////////////////

input  logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vpu_vtcu_req_vld_m1        ,   //VPU访问VTCU的请求valid指示信号, *说明：N路请求对应VTCM的N个Bank * VTCM req from VPU (could be load or store)
output logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vtcu_vpu_req_rdy_m1        ,   //VTCU接收VPU请求的ready指示信号
input  logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vpu_vtcu_req_wr_m1         ,   //VPU访问VTCU的请求类型。0：load， 1：store
input  logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VLQID_W:0]            vpu_vtcu_req_info_m1       ,   //请求携带的info信息 [3]: last_st标志，表示是否是某条store指令的最后一个请求 . [2:0]:vlq_id, 请求id
input  logic [`CHUNJUN_VTCM_BANK_N-1:0][20-1:0]       vpu_vtcu_req_addr_m1       ,  //VPU请求地址, 4byte对齐，VTCU忽略低2bit  *发出的地址可非对齐，VTCU根据访存位宽对齐访问，忽略低位
input  logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                          vpu_vtcu_req_wdata_m1      ,   //VPU访问VTCU store请求的写数据
input  logic [`CHUNJUN_VTCM_BANK_N-1:0][3:0]                           vpu_vtcu_req_wstrb_m1      ,   //VPU访问VTCU store请求的byte选通信号

output logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vtcu_vpu_rsp_vld_m3        ,   //VTCU在M3阶段向VPU发送的响应valid指示信号
input  logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vpu_vtcu_rsp_rdy_m3        ,   //VPU接收VTCU的响应ready指示信号 *说明：当前版本固接1
output logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                          vtcu_vpu_rsp_data_m3       ,   //VTCU向VPU发送的读响应数据（已纠错）
output logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VLQID_W:0]            vtcu_vpu_rsp_info_m3       ,   //vtcu返回的响应携带的info信息 [4]: wr, 0-load,1-store [3]:last_st标志 [2:0]:vlq_id, 请求id
output logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vtcu_vpu_rsp_raserr_m3     ,   //TCU向VPU发送读响应的成功指示信号 * 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error * 当配置不使能ECC时，不会返回error

// vtcu <-> ram
output logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vtcm_ram_cs                ,   //VTCM N个bank的片选信号
output logic [`CHUNJUN_VTCM_BANK_N-1:0]                                vtcm_ram_wr                ,   //VTCM N个bank的写指示信号。 0 - 读请求； 1 - 写请求
output logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_ADDR_W-1:0]  vtcm_ram_addr              ,   //VTCM N个bank的地址指示信号
output logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_DATA_W-1:0]  vtcm_ram_wen               ,   //VTCM N个bank的写选通信号信号，wen每1-bit对应wdata的1-bit
output logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_DATA_W-1:0]  vtcm_ram_wdata             ,   //VTCM N个bank的写数据
input  logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_DATA_W-1:0]  vtcm_ram_rdata             ,   //VTCM N个bank的读数据

// tcu <-> vpu
input  logic [1:0]                                                     vpu_tcu_ld_req_vld_m1      ,   //发送给TCU的Load请求有效信号, 2bit 分别表示两路load口，下同不赘述，两路bank口没有做bank路由，可能同时访问同一bank *Normal TCM (ITCM, DTCM0 or DTCM1) req from VPU (load only)
output logic [1:0]                                                     tcu_vpu_ld_req_rdy_m1      ,   //TCU接收load请求ready信号
input  logic [1:0][20-1:0]                            vpu_tcu_ld_req_addr_m1     ,                    //发送给TCU的Load请求地址（默认4B对齐，TCU忽略低2bit0） 每个内核的各个L1TCM分配了1MB的memory map space。 (不支持非对齐地址访问)
input  logic [1:0][2:0]                                                vpu_tcu_ld_req_route_m1    ,   //3'b001: 访问ITCM 3'b010: 访问DTCM0 3'b100: 访问DTCM1
input  logic [1:0][`CHUNJUN_VLQID_W-1:0]                               vpu_tcu_ld_req_vlqid_m1    ,   //请求对应的VPU Load buffer id

input  logic [1:0]                                                     vpu_tcu_ld_req_cancel_m2   ,   //M2 Stage发送给TCU的取消load请求指示信号
 
output logic [1:0]                                                     tcu_vpu_ld_rsp_vld_m3      ,   //TCU在M3 stage返回的Load数据响应有效信号
input  logic [1:0]                                                     vpu_tcu_ld_rsp_rdy_m3      ,   //VLSU接收TCU返回的读数据响应ready信号 当前版本固接1，不反压TCU的读数据响应
output logic [1:0][31:0]                                               tcu_vpu_ld_rsp_data_m3     ,   //TCU返回的Load数据（已纠错）
output logic [1:0][`CHUNJUN_VLQID_W-1:0]                               tcu_vpu_ld_rsp_vlqid_m3    ,   //TCU返回的Load数据对应的请求id
output logic [1:0]                                                     tcu_vpu_ld_rsp_raserr_m3   ,   //TCU返回的Load响应出现RAS错误指示（不可恢复的ECC错误） * 当配置使能ECC，并检测到2-bit error时，置1表示返回ras error * 当配置不使能ECC时，不会返回error
`endif // CHUNJUN_SUPPORT_V_EXT

/////////////////////////////////
// RAS <-> TCU
/////////////////////////////////

output logic [4-1:0]                            tcu_ras_valid              ,   // 模块向RAS发送Error Valid指示信号，TCU上报RAS有4个信号 [0] : ITCM中发生的错误 [1] : DTCM0中发生的错误 [2] : DTCM1中发生的错误 [3] : VTCM中发生的错误
output logic [4-1:0]                            tcu_ras_ce                 ,   // 上报的错误是Corrected Errors
output logic [4-1:0]                            tcu_ras_ued                ,   // 上报的错误是Uncorrected Errors Defered，Tie 0
output logic [4-1:0]                            tcu_ras_uec                ,   // 上报的错误是Uncorreted Errors Critical
output logic [4-1:0] [1:0]                      tcu_ras_priority           ,   // 上报的Error的优先级
output logic [4-1:0] [2:0]                      tcu_ras_tt                 ,   // 上报的Error的transaction type： 0: unspecified 4: Explicit read 5: Explicit write 6: Implicit read 7: Implicit write 其余编码为reserved。
output logic [4-1:0]                            tcu_ras_scrub              ,   // 上报的Error是否在memory中已被修正。
output logic [4-1:0] [7:0]                      tcu_ras_ec                 ,   // 上报的Error的Error Code Encodings
output logic [4-1:0] [32-1:0]        tcu_ras_addr               ,   // 触发上报的Error的地址
output logic [4-1:0] [3:0]                      tcu_ras_aec                ,   // 上报的Error的辅助编码信息
output logic [4-1:0]                            tcu_ras_tag                ,   // Error是否发生在tag， Tie 0
output logic [4-1:0] [3:0]                      tcu_ras_way                    // Error发生在cache中的哪一个way，Tie 0
 
);

//=================================================================================
// Local Parameters
//=================================================================================

localparam MUX_ITCM_ICU  = 0; //ITCM的ICU
localparam MUX_ITCM_SLV  = 1; //ITCM的SLV
localparam MUX_ITCM_LSU0 = 2; //ITCM的LSU0
localparam MUX_ITCM_LSU1 = 3; //ITCM的LSU1
localparam MUX_ITCM_SBU  = 4; //ITCM的SBU
localparam MUX_ITCM_VPU0 = 5; //ITCM的VPU0
localparam MUX_ITCM_VPU1 = 6; //ITCM的VPU1

localparam TCM_ID_IM_1_W = ($clog2(4)   > ($clog2(6) + 1)       ) ? $clog2(4)   : ($clog2(6) + 1);
localparam TCM_ID_IM_2_W = ($clog2(6) > (8 + 2 + 3)) ? $clog2(6) : (8 + 2 + 3);
`ifdef CHUNJUN_SUPPORT_V_EXT
localparam TCM_ID_IM_3_W = ( TCM_ID_IM_1_W       > (`CHUNJUN_VLQID_W+1)   ) ?  TCM_ID_IM_1_W       : (`CHUNJUN_VLQID_W+1);
// Longest ID width = TCM_ID_IM_W
localparam TCM_ID_IM_W   = ( TCM_ID_IM_2_W       >  TCM_ID_IM_3_W         ) ?  TCM_ID_IM_2_W       :  TCM_ID_IM_3_W;
`else // CHUNJUN_SUPPORT_V_EXT
localparam TCM_ID_IM_W   = ( TCM_ID_IM_2_W       >  TCM_ID_IM_1_W         ) ?  TCM_ID_IM_2_W       :  TCM_ID_IM_1_W;
`endif // CHUNJUN_SUPPORT_V_EXT
 
localparam TCM_ID_W = TCM_ID_IM_W + 4;   // 4 = EXT_ID_W

// Add three more bits to indicate request source.
// 4'b0000 - ICU
// 4'b0001 - LSU[0]
// 4'b0101 - LSU[1]
// 4'b0010 - SBU
// 4'b0011 - SLV-BUS
// 4'b1000 - VPU[0]
// 4'b1001 - VPU[1]
localparam EXT_ID_ICU  = 4'b0000; 
localparam EXT_ID_LSU0 = 4'b0001;
localparam EXT_ID_LSU1 = 4'b0101;
localparam EXT_ID_SBU  = 4'b0010;
localparam EXT_ID_SLV  = 4'b0011;
localparam EXT_ID_VPU0 = 4'b1000;
localparam EXT_ID_VPU1 = 4'b1001;
localparam EXT_ID_VTCM = 4'b1010;   // VPU to VTCM

`ifdef CHUNJUN_SUPPORT_A_EXT
localparam DTCM_ATOP_EN = 1;
`else 
localparam DTCM_ATOP_EN = 0;
`endif

`ifdef CHUNJUN_SUPPORT_MEM_ECC
localparam TCM_ECC_EN = 1;
`else
localparam TCM_ECC_EN = 0;
`endif

localparam ITCM_WAIT_EN = 0;
 
localparam DTCM0_WAIT_EN = 0;
 
localparam DTCM1_WAIT_EN = 0;

localparam VTCM_WAIT_EN = 0;
 
localparam DTCM_WDATA_POST_ENC_W = 2 * `CHUNJUN_DTCM_RAM_DATA_W;
 
localparam TCM_HOLD_EN = DTCM_ATOP_EN | TCM_ECC_EN;

localparam MUX_ICU_ITCM  = 0;
localparam MUX_ICU_DTCM0 = 1;
localparam MUX_ICU_DTCM1 = 2;

localparam MUX_LSU_DTCM0_LO = 0;
localparam MUX_LSU_DTCM0_HI = 1;
localparam MUX_LSU_DTCM1_LO = 2;
localparam MUX_LSU_DTCM1_HI = 3;
localparam MUX_LSU_ITCM_LO  = 4;
localparam MUX_LSU_ITCM_HI  = 5;
localparam MUX_LSU_VTCM     = 6;

localparam MUX_SBU_DTCM0 = 0;
localparam MUX_SBU_DTCM1 = 1;
localparam MUX_SBU_ITCM  = 2;
localparam MUX_SBU_VTCM  = 3;

localparam MUX_SBU_ATOP_DTCM0_LO = 0;
localparam MUX_SBU_ATOP_DTCM0_HI = 1;
localparam MUX_SBU_ATOP_DTCM1_LO = 2;
localparam MUX_SBU_ATOP_DTCM1_HI = 3;

localparam MUX_SLV_ITCM  = 0;
localparam MUX_SLV_DTCM0 = 1;
localparam MUX_SLV_DTCM1 = 2;
localparam MUX_SLV_VTCM  = 3;

localparam MUX_VPU_DTCM0_LO = 0;
localparam MUX_VPU_DTCM0_HI = 1;
localparam MUX_VPU_DTCM1_LO = 2;
localparam MUX_VPU_DTCM1_HI = 3;
localparam MUX_VPU_ITCM_LO  = 4;
localparam MUX_VPU_ITCM_HI  = 5;
 
localparam RAS_ITCM  = 0;
localparam RAS_DTCM0 = 1;
localparam RAS_DTCM1 = 2;
localparam RAS_VTCM  = 3;
 
localparam RAS_SRC_LD     = 0;
localparam RAS_SRC_ST     = 1;
localparam RAS_SRC_SLV_LD = 2;
localparam RAS_SRC_SLV_ST = 3;
localparam RAS_SRC_IF     = 4;
 
//=================================================================================
// Local Variables 
//=================================================================================

// Description of Abbreviation
//
// * iarb : ITCM arbiter.
// * ldxb0: DTCM0 load xbar, used to distribute load0/load1 request to DTCM0 bank_lo and bank_hi.
// * parb0: DTCM0 pre arbiter, used to arbitrate ICU/SBU/SLV-bus request to DTCM0.
// * darb0: DTCM0 main arbiter.
// * ldxb1: DTCM1 load xbar, used to distribute load0/load1 request to DTCM1 bank_lo and bank_hi.
// * parb1: DTCM1 pre arbiter, used to arbitrate ICU/SBU/SLV-bus request to DTCM1.
// * darb1: DTCM1 main arbiter.

//=================================================================================
// ITCM 仲裁器接口信号
//=================================================================================
// 各主设备向ITCM仲裁器发送请求和接收响应的握手信号

// 主设备请求有效信号（输入到仲裁器）
logic                                                            icu_iarb_req_vld ; // ICU指令缓存单元请求有效
logic                                                            lsu_ld0_iarb_req_vld ; // LSU0加载单元请求有效
logic                                                            lsu_ld1_iarb_req_vld ; // LSU1加载单元请求有效
logic                                                            vpu_ld0_iarb_req_vld; // VPU0向量加载单元请求有效
logic                                                            vpu_ld1_iarb_req_vld; // VPU1向量加载单元请求有效
logic                                                            sbu_iarb_req_vld ; // SBU系统总线单元请求有效
logic                                                            slv_iarb_req_vld ; // SLV从设备总线请求有效

// 仲裁器响应就绪信号（输出到主设备）
logic                                                            iarb_icu_req_rdy ; // ICU请求被仲裁器接受
logic                                                            iarb_lsu0_req_rdy; // LSU0请求被仲裁器接受
logic                                                            iarb_lsu1_req_rdy; // LSU1请求被仲裁器接受
logic                                                            iarb_sbu_req_rdy ; // SBU请求被仲裁器接受
logic                                                            iarb_slv_req_rdy ; // SLV请求被仲裁器接受
logic                                                            iarb_vpu0_req_rdy; // VPU0请求被仲裁器接受
logic                                                            iarb_vpu1_req_rdy; // VPU1请求被仲裁器接受
 
//=================================================================================
// DTCM0 仲裁器接口信号
//=================================================================================
// 各主设备向DTCM0仲裁器发送请求和接收响应的握手信号

// 主设备请求有效信号（输入到DTCM0仲裁器）
logic                                                            icu_dtcm0_req_vld; // ICU向DTCM0的请求有效
logic [1:0]                                                      lsu_dtcm0_req_vld; // LSU0/1向DTCM0的请求有效（2位向量）
logic                                                            sbu_dtcm0_req_vld; // SBU向DTCM0的请求有效
logic                                                            slv_dtcm0_req_vld; // SLV向DTCM0的请求有效
logic [1:0]                                                      vpu_dtcm0_req_vld; // VPU0/1向DTCM0的请求有效（2位向量）
logic [1:0][19:0]                                                vpu_dtcm0_req_addr; // VPU0/1向DTCM0的请求地址（2个20位地址）

// DTCM0仲裁器响应就绪信号（输出到主设备）
logic                                                            dtcm0_icu_req_rdy; // DTCM0对ICU请求的响应
logic [1:0]                                                      dtcm0_lsu_req_rdy; // DTCM0对LSU0/1请求的响应（2位向量）
logic                                                            dtcm0_sbu_req_rdy; // DTCM0对SBU请求的响应
logic                                                            dtcm0_slv_req_rdy; // DTCM0对SLV请求的响应
logic [1:0]                                                      dtcm0_vpu_req_rdy; // DTCM0对VPU0/1请求的响应（2位向量）

//=================================================================================
// DTCM1 仲裁器接口信号
//=================================================================================
// 各主设备向DTCM1仲裁器发送请求和接收响应的握手信号

// 主设备请求有效信号（输入到DTCM1仲裁器）
logic                                                            icu_dtcm1_req_vld; // ICU向DTCM1的请求有效
logic [1:0]                                                      lsu_dtcm1_req_vld; // LSU0/1向DTCM1的请求有效（2位向量）
logic                                                            ld1_dtcm1_req_vld; // LSU1向DTCM1的请求有效（独立信号）
logic                                                            sbu_dtcm1_req_vld; // SBU向DTCM1的请求有效
logic                                                            slv_dtcm1_req_vld; // SLV向DTCM1的请求有效
logic [1:0]                                                      vpu_dtcm1_req_vld; // VPU0/1向DTCM1的请求有效（2位向量）
logic [1:0][19:0]                                                vpu_dtcm1_req_addr; // VPU0/1向DTCM1的请求地址（2个20位地址）

// 中间信号
logic                                                            slv_req_grt; // SLV请求被授予（中间信号）

// DTCM1仲裁器响应就绪信号（输出到主设备）
logic                                                            dtcm1_icu_req_rdy; // DTCM1对ICU请求的响应
logic [1:0]                                                      dtcm1_lsu_req_rdy; // DTCM1对LSU0/1请求的响应（2位向量）
logic                                                            dtcm1_sbu_req_rdy; // DTCM1对SBU请求的响应
logic                                                            dtcm1_slv_req_rdy; // DTCM1对SLV请求的响应
logic [1:0]                                                      dtcm1_vpu_req_rdy; // DTCM1对VPU0/1请求的响应（2位向量）
 
//=================================================================================
// VTCM 仲裁器接口信号
//=================================================================================
// 各主设备向VTCM仲裁器发送请求和接收响应的握手信号

// 主设备请求有效信号（输入到VTCM仲裁器）
logic [1:0]                                                      lsu_vtcm_req_vld; // LSU0/1向VTCM的请求有效（2位向量）
logic                                                            sbu_vtcm_req_vld; // SBU向VTCM的请求有效
logic                                                            slv_vtcm_req_vld ; // SLV向VTCM的请求有效

// VTCM仲裁器响应就绪信号（输出到主设备）
logic [1:0]                                                      vtcm_lsu_req_rdy; // VTCM对LSU0/1请求的响应（2位向量）
logic                                                            vtcm_sbu_req_rdy; // VTCM对SBU请求的响应
logic                                                            vtcm_slv_req_rdy; // VTCM对SLV请求的响应
 
//=================================================================================
// 请求ID对齐和取消信号
//=================================================================================
// 用于请求ID对齐和VPU请求取消控制

// 对齐后的请求ID信号
logic [TCM_ID_W-1:0]                                             aln_req_id_icu; // ICU对齐后的请求ID
logic [1:0][TCM_ID_W-1:0]                                        aln_req_id_lsu; // LSU0/1对齐后的请求ID（2个ID）
logic [TCM_ID_W-1:0]                                             aln_req_id_sbu; // SBU对齐后的请求ID
logic [TCM_ID_W-1:0]                                             aln_req_id_slv; // SLV对齐后的请求ID
logic [1:0][TCM_ID_W-1:0]                                        aln_req_id_vpu; // VPU0/1对齐后的请求ID（2个ID）

// 请求取消和数据处理信号
logic [1:0]                                                      vpu_tcu_cancel_m2; // VPU0/1在M2阶段的请求取消信号
logic [63:0]                                                     sbu_req_wdata_atop_mux; // SBU原子操作的写数据复用信号
 
//=================================================================================
// ECC编码支持信号（可选）
//=================================================================================
// 当CHUNJUN_SUPPORT_MEM_ECC宏定义时生效，用于内存ECC编码

`ifdef CHUNJUN_SUPPORT_MEM_ECC
// SBU ECC编码信号
logic [6:0]                                                      enc_code_sbu_lo; // SBU低32位数据的ECC编码（7位）
logic [6:0]                                                      enc_code_sbu_hi; // SBU高32位数据的ECC编码（7位）
logic [7:0]                                                      enc_code_sbu_64; // SBU 64位数据的ECC编码（8位）
logic [38:0]                                                     sbu_wdata_post_enc_lo; // SBU低32位数据+ECC编码（39位）
logic [38:0]                                                     sbu_wdata_post_enc_hi; // SBU高32位数据+ECC编码（39位）
logic [77:0]                                                     sbu_wdata_post_enc_32; // SBU 32位数据+ECC编码（78位）
logic [71:0]                                                     sbu_wdata_post_enc_64; // SBU 64位数据+ECC编码（72位）

// BMU ECC编码信号
logic [6:0]                                                      enc_code_bmu_lo; // BMU低32位数据的ECC编码（7位）
logic [6:0]                                                      enc_code_bmu_hi; // BMU高32位数据的ECC编码（7位）
logic [7:0]                                                      enc_code_bmu_64; // BMU 64位数据的ECC编码（8位）
logic [38:0]                                                     bmu_wdata_post_enc_lo; // BMU低32位数据+ECC编码（39位）
logic [38:0]                                                     bmu_wdata_post_enc_hi; // BMU高32位数据+ECC编码（39位）
logic [77:0]                                                     bmu_wdata_post_enc_32; // BMU 32位数据+ECC编码（78位）
logic [71:0]                                                     bmu_wdata_post_enc_64; // BMU 64位数据+ECC编码（72位）
`endif //CHUNJUN_SUPPORT_MEM_ECC
//=================================================================================
// DTCM写数据信号
//=================================================================================
// SBU和BMU向DTCM的写数据信号

logic [(2*`CHUNJUN_DTCM_RAM_DATA_W)-1:0]                         sbu_dtcm_wdata; // SBU向DTCM的写数据（双倍DTCM数据宽度）
logic [(2*`CHUNJUN_DTCM_RAM_DATA_W)-1:0]                         bmu_dtcm_wdata; // BMU向DTCM的写数据（双倍DTCM数据宽度）

//=================================================================================
// BMU请求缓冲和握手信号
//=================================================================================
// 用于BMU请求的缓冲管理和握手控制

// BMU握手控制
logic                                                            bmu_tcu_req_hdsk; // BMU与TCU的请求握手信号
logic                                                            bmu_req_buf_empty; // BMU请求缓冲区空标志
logic                                                            bmu_req_hi_sent; // BMU高64位请求已发送标志

// 缓冲区有效控制信号
logic                                                            bmu_req_buf_vld_set; // 设置缓冲区有效标志
logic                                                            bmu_req_buf_vld_clr; // 清除缓冲区有效标志
logic                                                            bmu_req_buf_vld_en; // 缓冲区有效使能
logic                                                            bmu_req_buf_vld_d; // 缓冲区有效信号（组合逻辑）
logic                                                            bmu_req_buf_vld_q; // 缓冲区有效信号（寄存器）

// 缓冲区信息控制
logic                                                            bmu_req_info_en; // 缓冲区信息更新使能

// 缓冲区地址信号（d=组合逻辑，q=寄存器）
logic [20-1:0]                                  bmu_req_buf_addr_d; // 缓冲区地址（组合逻辑）
logic [20-1:0]                                  bmu_req_buf_addr_q; // 缓冲区地址（寄存器）

// 缓冲区路由信号
logic [3:0]                                                      bmu_req_buf_route_d; // 缓冲区路由（组合逻辑）
logic [3:0]                                                      bmu_req_buf_route_q; // 缓冲区路由（寄存器）

// 缓冲区写控制信号
logic                                                            bmu_req_buf_wr_d; // 缓冲区写使能（组合逻辑）
logic                                                            bmu_req_buf_wr_q; // 缓冲区写使能（寄存器）

// 缓冲区写数据信号
logic [63:0]                                                     bmu_req_buf_wdata_d; // 缓冲区写数据（组合逻辑）
logic [63:0]                                                     bmu_req_buf_wdata_q; // 缓冲区写数据（寄存器）

// 缓冲区写选通信号
logic [7:0]                                                      bmu_req_buf_wstrb_d; // 缓冲区写选通（组合逻辑）
logic [7:0]                                                      bmu_req_buf_wstrb_q; // 缓冲区写选通（寄存器）

// 缓冲区ID信号
logic [(8 + 2 + 3)-1:0]                              bmu_req_buf_id_d; // 缓冲区ID（组合逻辑）
logic [(8 + 2 + 3)-1:0]                              bmu_req_buf_id_q; // 缓冲区ID（寄存器）

// 请求地址分解信号
logic [20-1:0]                                  bmu_req_addr_lo; // BMU请求低地址
logic [20-1:0]                                  bmu_req_addr_hi; // BMU请求高地址

// 请求复用信号
logic                                                            bmu_req_vld_mux; // BMU请求有效复用信号
logic [20-1:0]                                  bmu_req_addr_mux; // BMU请求地址复用信号
logic [3:0]                                                      bmu_req_route_mux; // BMU请求路由复用信号
logic                                                            bmu_req_wr_mux; // BMU请求写使能复用信号

// 请求数据复用信号
logic [63:0]                                                     bmu_req_wdata_lo; // BMU请求低64位数据
logic [63:0]                                                     bmu_req_wdata_hi; // BMU请求高64位数据
logic [63:0]                                                     bmu_req_wdata_mux; // BMU请求数据复用信号

// 请求选通复用信号
logic [7:0]                                                      bmu_req_wstrb_lo; // BMU请求低8位选通
logic [7:0]                                                      bmu_req_wstrb_hi; // BMU请求高8位选通
logic [7:0]                                                      bmu_req_wstrb_mux; // BMU请求选通复用信号

// 请求ID复用信号
logic [(8 + 2 + 3)-1:0]                              bmu_req_id_mux; // BMU请求ID复用信号
 
//=================================================================================
// CSR ECC注入控制信号
//=================================================================================
// 用于控制ECC错误注入的CSR寄存器信号

// CSR控制寄存器信号
logic                                                            csr_ecc_en; // 全局ECC使能信号（来自CSR）
logic                                                            csr_inject_en; // ECC错误注入使能信号（来自CSR）
logic [3:0]                                                      csr_inject_dest; // ECC注入目标选择（0100:ITCM, 0101:DTCM0, 0110:DTCM1, 0111:VTCM）
logic [3:0]                                                      csr_inject_bank; // ECC注入bank选择（按实现对齐）
logic [31:0]                                                     csr_inject_bitmapl; // ECC注入位图低32位（控制哪些位注入错误）
logic [31:0]                                                     csr_inject_bitmaph; // ECC注入位图高32位（控制哪些位注入错误）

// 各TCM的ECC注入使能信号
logic                                                            ecc_inject_itcm; // ITCM的ECC错误注入使能
logic                                                            ecc_inject_dtcm0; // DTCM0的ECC错误注入使能
logic                                                            ecc_inject_dtcm1; // DTCM1的ECC错误注入使能
logic                                                            ecc_inject_vtcm; // VTCM的ECC错误注入使能

//=================================================================================
// TCM读数据信号（ECC注入前/后）
//=================================================================================
// 各TCM的读数据信号，包括ECC注入前的原始数据和注入后的数据

// ITCM读数据信号
logic [63:0]                                                     itcm_rdata_pre; // ITCM原始读数据（ECC注入前）
logic [`CHUNJUN_ITCM_RAM_DATA_W-1:0]                             itcm_rdata; // ITCM最终读数据（ECC注入后）

// DTCM0读数据信号
logic [31:0]                                                     dtcm0_rdata_lo_pre; // DTCM0 lo bank原始读数据（ECC注入前）
logic [31:0]                                                     dtcm0_rdata_hi_pre; // DTCM0 hi bank原始读数据（ECC注入前）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dtcm0_rdata_lo; // DTCM0 lo bank最终读数据（ECC注入后）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dtcm0_rdata_hi; // DTCM0 hi bank最终读数据（ECC注入后）

// DTCM1读数据信号
logic [31:0]                                                     dtcm1_rdata_lo_pre; // DTCM1 lo bank原始读数据（ECC注入前）
logic [31:0]                                                     dtcm1_rdata_hi_pre; // DTCM1 hi bank原始读数据（ECC注入前）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dtcm1_rdata_lo; // DTCM1 lo bank最终读数据（ECC注入后）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dtcm1_rdata_hi; // DTCM1 hi bank最终读数据（ECC注入后）

// VTCM读数据信号
logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                           vtcm_rdata_pre; // VTCM各bank原始读数据（ECC注入前）
logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_DATA_W-1:0]   vtcm_rdata; // VTCM各bank最终读数据（ECC注入后）

//=================================================================================
// ITCM仲裁器接口信号
//=================================================================================
// ITCM仲裁器的请求和响应信号

// 仲裁器请求信号
logic [6:0]                                                      iarb_req; // 各主设备向ITCM仲裁器的请求有效信号（7位向量）
logic [6:0]                                                      iarb_grt; // ITCM仲裁器对各主设备的响应信号（7位向量）
logic [6:0][19:0]                                                iarb_req_addr; // 各主设备向ITCM仲裁器的请求地址（7个20位地址）
logic [6:0][TCM_ID_W-1:0]                                        iarb_req_id  ; // 各主设备向ITCM仲裁器的请求ID（7个ID）

// 仲裁器写操作信号
logic [1:0]                                                      iarb_req_wr  ; // ITCM仲裁器的写请求信号（2位向量）
logic [1:0][`CHUNJUN_ITCM_RAM_DATA_W-1:0]                        iarb_req_wdata; // ITCM仲裁器的写数据（2个数据）
logic [1:0][7:0]                                                 iarb_req_wstrb; // ITCM仲裁器的写选通信号（2个8位选通）
logic [1:0]                                                      iarb_grt_wo; // ITCM仲裁器的写操作响应信号（2位向量）

// 写操作控制信号
logic [1:0]                                                      iarb_req_wo; // ITCM仲裁器的写操作请求信号（2位向量）
logic                                                            ibank_req_wr_pre; // ITCM bank的写请求预处理信号
 
//=================================================================================
// ITCM Bank接口信号（M1阶段）
//=================================================================================
// ITCM bank的请求和响应信号

// ITCM bank请求信号（M1阶段）
logic                                                            ibank_req_vld_m1  ; // ITCM bank请求有效信号
logic                                                            ibank_req_rdy_m1  ; // ITCM bank请求就绪信号
logic [19:0]                                                     ibank_req_addr_m1 ; // ITCM bank请求地址（20位）
logic [TCM_ID_W-1:0]                                             ibank_req_id_m1   ; // ITCM bank请求ID
logic                                                            ibank_req_wr_m1   ; // ITCM bank写使能信号（0=读，1=写）
logic [`CHUNJUN_ITCM_RAM_DATA_W-1:0]                             ibank_req_wdata_m1; // ITCM bank写数据
logic [7:0]                                                      ibank_req_wstrb_m1; // ITCM bank写选通信号（字节级使能）

// ITCM bank状态和控制信号
logic                                                            ibank_into_partial_m1; // ITCM bank进入部分写状态
logic [63:0]                                                     ibank_hold_wdata  ; // ITCM bank保持的写数据
logic [7:0]                                                      ibank_hold_wstrb  ; // ITCM bank保持的写选通
logic                                                            ibank_busy        ; // ITCM bank忙状态（正在处理请求）
logic                                                            ibank_idle        ; // ITCM bank空闲状态（可接受新请求）

// ITCM bank响应信号（M2阶段）
logic                                                            ibank_rsp_vld_m2  ; // ITCM bank响应有效信号
logic [TCM_ID_W-1:0]                                             ibank_rsp_id_m2   ; // ITCM bank响应ID
logic [63:0]                                                     ibank_rsp_data_m2 ; // ITCM bank响应数据
logic                                                            ibank_rsp_se_m2   ; // ITCM bank单比特错误标志
logic                                                            ibank_rsp_de_m2   ; // ITCM bank双比特错误标志
logic [19:0]                                                     ibank_rsp_addr_m2 ; // ITCM bank响应地址

// ITCM bank响应信号（M3阶段）
logic [19:0]                                                     ibank_rsp_addr_m3 ; // ITCM bank响应地址（M3阶段）
logic                                                            ibank_rsp_vld_m3  ; // ITCM bank响应有效信号（M3阶段）
logic [TCM_ID_W-1:0]                                             ibank_rsp_id_m3   ; // ITCM bank响应ID（M3阶段）
logic [63:0]                                                     ibank_rsp_data_m3 ; // ITCM bank响应数据（M3阶段）
logic                                                            ibank_rsp_se_m3   ; // ITCM bank单比特错误标志（M3阶段）
logic                                                            ibank_rsp_de_m3   ; // ITCM bank双比特错误标志（M3阶段）

// ITCM bank RAS报告信号
logic                                                            ibank_rsp_vld_ras ; // ITCM bank RAS报告有效信号
logic [TCM_ID_W-1:0]                                             ibank_rsp_id_ras  ; // ITCM bank RAS报告ID
logic                                                            ibank_rsp_se_ras  ; // ITCM bank RAS报告单比特错误
logic                                                            ibank_rsp_de_ras  ; // ITCM bank RAS报告双比特错误
logic                                                            ibank_rsp_wr_ras  ; // ITCM bank RAS报告写操作标志
logic [19:0]                                                     ibank_rsp_addr_ras; // ITCM bank RAS报告地址
 
//=================================================================================
// DTCM0 Bank 请求接口信号（M1阶段）
//=================================================================================
// DTCM0分为lo和hi两个32位bank，每个bank有独立的请求接口

// DTCM0 lo bank 请求信号
logic                                                            dbank0_lo_req_vld_m1   ; // lo bank请求有效信号
logic                                                            dbank0_lo_req_rdy_m1   ; // lo bank请求就绪信号
logic [19:0]                                                     dbank0_lo_req_addr_m1  ; // lo bank请求地址（20位）
logic [TCM_ID_W-1:0]                                             dbank0_lo_req_id_m1    ; // lo bank请求ID
logic                                                            dbank0_lo_req_wr_m1    ; // lo bank写使能信号（0=读，1=写）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dbank0_lo_req_wdata_m1 ; // lo bank写数据
logic [3:0]                                                      dbank0_lo_req_wstrb_m1 ; // lo bank写选通信号（字节级使能）
logic [5:0]                                                      dbank0_lo_req_atop_m1  ; // lo bank原子操作码

// DTCM0 hi bank 请求信号
logic                                                            dbank0_hi_req_vld_m1   ; // hi bank请求有效信号
logic                                                            dbank0_hi_req_rdy_m1   ; // hi bank请求就绪信号
logic [19:0]                                                     dbank0_hi_req_addr_m1  ; // hi bank请求地址（20位）
logic [TCM_ID_W-1:0]                                             dbank0_hi_req_id_m1    ; // hi bank请求ID
logic                                                            dbank0_hi_req_wr_m1    ; // hi bank写使能信号（0=读，1=写）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dbank0_hi_req_wdata_m1 ; // hi bank写数据
logic [3:0]                                                      dbank0_hi_req_wstrb_m1 ; // hi bank写选通信号（字节级使能）
logic [5:0]                                                      dbank0_hi_req_atop_m1  ; // hi bank原子操作码
//=================================================================================
// DTCM0 Bank 状态和控制信号
//=================================================================================
// 用于指示DTCM0各bank的工作状态和特殊操作模式

// 部分写和原子操作状态指示
logic                                                            dbank0_lo_into_partial_m1; // lo bank进入部分写状态
logic                                                            dbank0_hi_into_partial_m1; // hi bank进入部分写状态
logic                                                            dbank0_lo_into_atomic_m1; // lo bank进入原子操作状态
logic                                                            dbank0_hi_into_atomic_m1; // hi bank进入原子操作状态

// Bank忙闲状态指示
logic                                                            dbank0_lo_busy         ; // lo bank忙状态（正在处理请求）
logic                                                            dbank0_lo_idle         ; // lo bank空闲状态（可接受新请求）
logic                                                            dbank0_hi_busy         ; // hi bank忙状态（正在处理请求）
logic                                                            dbank0_hi_idle         ; // hi bank空闲状态（可接受新请求）
 
//=================================================================================
// DTCM0 Bank 保持寄存器信号
//=================================================================================
// 用于DTCM0部分写和原子操作的数据保持

// 整体状态控制
logic                                                            dbank0_into_partial_m1 ; // DTCM0进入部分写状态
logic                                                            dbank0_into_atomic_m1  ; // DTCM0进入原子操作状态

// 保持数据控制信号
logic                                                            dbank0_hold_wdata_en   ; // 保持写数据使能
logic [63:0]                                                     dbank0_hold_wdata_m1   ; // 保持写数据（M1阶段）
logic                                                            dbank0_hold_wstrb_en   ; // 保持写选通使能
logic [7:0]                                                      dbank0_hold_wstrb_m1   ; // 保持写选通（M1阶段）

// 保持数据信号
logic [63:0]                                                     dbank0_hold_wdata      ; // 保持的写数据（64位）
logic [7:0]                                                      dbank0_hold_wstrb      ; // 保持的写选通（8位）

// 分解的保持数据信号
logic [31:0]                                                     dbank0_hold_wdata_lo   ; // 保持的写数据低32位
logic [31:0]                                                     dbank0_hold_wdata_hi   ; // 保持的写数据高32位
logic [3:0]                                                      dbank0_hold_wstrb_lo   ; // 保持的写选通低4位
logic [3:0]                                                      dbank0_hold_wstrb_hi   ; // 保持的写选通高4位
 
//=================================================================================
// DTCM0 Bank 原子操作信号
//=================================================================================
// 用于DTCM0原子操作的控制和比较

// 原子操作保持信号
logic [5:0]                                                      dbank0_lo_hold_atop_m1 ; // lo bank原子操作码保持（M1阶段）
logic [5:0]                                                      dbank0_hi_hold_atop_m1 ; // hi bank原子操作码保持（M1阶段）
logic [5:0]                                                      dbank0_hold_atop_lo    ; // 保持的原子操作码低32位
logic [5:0]                                                      dbank0_hold_atop_hi    ; // 保持的原子操作码高32位

// 原子操作比较信号
logic [31:0]                                                     dbank0_atop_cmp_val_m1 ; // 原子操作比较值（M1阶段）
logic [31:0]                                                     dbank0_hold_cmp_val    ; // 保持的原子操作比较值 
 
//=================================================================================
// DTCM0 lo Bank 响应信号
//=================================================================================
// DTCM0 lo bank的响应信号，包括M2、M3阶段和RAS报告

// DTCM0 lo bank响应信号（M2阶段）
logic                                                            dbank0_lo_rsp_vld_m2   ; // lo bank响应有效信号
logic [TCM_ID_W-1:0]                                             dbank0_lo_rsp_id_m2    ; // lo bank响应ID
logic [31:0]                                                     dbank0_lo_rsp_data_m2  ; // lo bank响应数据
logic                                                            dbank0_lo_rsp_se_m2    ; // lo bank单比特错误标志
logic                                                            dbank0_lo_rsp_de_m2    ; // lo bank双比特错误标志
logic [19:0]                                                     dbank0_lo_rsp_addr_m2  ; // lo bank响应地址

// DTCM0 lo bank响应信号（M3阶段）
logic                                                            dbank0_lo_rsp_vld_m3   ; // lo bank响应有效信号（M3阶段）
logic [TCM_ID_W-1:0]                                             dbank0_lo_rsp_id_m3    ; // lo bank响应ID（M3阶段）
logic [31:0]                                                     dbank0_lo_rsp_data_m3  ; // lo bank响应数据（M3阶段）
logic                                                            dbank0_lo_rsp_se_m3    ; // lo bank单比特错误标志（M3阶段）
logic                                                            dbank0_lo_rsp_de_m3    ; // lo bank双比特错误标志（M3阶段）
logic [19:0]                                                     dbank0_lo_rsp_addr_m3  ; // lo bank响应地址（M3阶段）

// DTCM0 lo bank原子操作状态信号
logic                                                            dbank0_lo_atop_b_infly_m3; // lo bank原子操作B阶段进行中（M3阶段）
logic                                                            dbank0_lo_atop_r_infly_m3; // lo bank原子操作R阶段进行中（M3阶段）

// DTCM0 lo bank RAS报告信号
logic                                                            dbank0_lo_rsp_vld_ras ; // lo bank RAS报告有效信号
logic [TCM_ID_W-1:0]                                             dbank0_lo_rsp_id_ras  ; // lo bank RAS报告ID
logic                                                            dbank0_lo_rsp_se_ras  ; // lo bank RAS报告单比特错误
logic                                                            dbank0_lo_rsp_de_ras  ; // lo bank RAS报告双比特错误
logic                                                            dbank0_lo_rsp_wr_ras  ; // lo bank RAS报告写操作标志
logic [19:0]                                                     dbank0_lo_rsp_addr_ras; // lo bank RAS报告地址
 
//=================================================================================
// DTCM0 hi Bank 响应信号
//=================================================================================
// DTCM0 hi bank的响应信号，包括M2、M3阶段和RAS报告

// DTCM0 hi bank响应信号（M2阶段）
logic                                                            dbank0_hi_rsp_vld_m2   ; // hi bank响应有效信号
logic [TCM_ID_W-1:0]                                             dbank0_hi_rsp_id_m2    ; // hi bank响应ID
logic [31:0]                                                     dbank0_hi_rsp_data_m2  ; // hi bank响应数据
logic                                                            dbank0_hi_rsp_se_m2    ; // hi bank单比特错误标志
logic                                                            dbank0_hi_rsp_de_m2    ; // hi bank双比特错误标志
logic                                                            dbank0_hi_rsp_wr_m2    ; // hi bank写操作标志（M2阶段）
logic                                                            dbank0_hi_rsp_wr_m3    ; // hi bank写操作标志（M3阶段）
logic [19:0]                                                     dbank0_hi_rsp_addr_m2  ; // hi bank响应地址

// DTCM0 hi bank响应信号（M3阶段）
logic                                                            dbank0_hi_rsp_vld_m3   ; // hi bank响应有效信号（M3阶段）
logic [TCM_ID_W-1:0]                                             dbank0_hi_rsp_id_m3    ; // hi bank响应ID（M3阶段）
logic [31:0]                                                     dbank0_hi_rsp_data_m3  ; // hi bank响应数据（M3阶段）
logic                                                            dbank0_hi_rsp_se_m3    ; // hi bank单比特错误标志（M3阶段）
logic                                                            dbank0_hi_rsp_de_m3    ; // hi bank双比特错误标志（M3阶段）
logic [19:0]                                                     dbank0_hi_rsp_addr_m3  ; // hi bank响应地址（M3阶段）

// DTCM0 hi bank原子操作状态信号
logic                                                            dbank0_hi_atop_b_infly_m3; // hi bank原子操作B阶段进行中（M3阶段）
logic                                                            dbank0_hi_atop_r_infly_m3; // hi bank原子操作R阶段进行中（M3阶段）

// DTCM0 hi bank RAS报告信号
logic                                                            dbank0_hi_rsp_vld_ras ; // hi bank RAS报告有效信号
logic [TCM_ID_W-1:0]                                             dbank0_hi_rsp_id_ras  ; // hi bank RAS报告ID
logic                                                            dbank0_hi_rsp_se_ras  ; // hi bank RAS报告单比特错误
logic                                                            dbank0_hi_rsp_de_ras  ; // hi bank RAS报告双比特错误
logic                                                            dbank0_hi_rsp_wr_ras  ; // hi bank RAS报告写操作标志
logic [19:0]                                                     dbank0_hi_rsp_addr_ras; // hi bank RAS报告地址

//=================================================================================
// DTCM1 Bank 请求接口信号（M1阶段）
//=================================================================================
// DTCM1分为lo和hi两个32位bank，每个bank有独立的请求接口

// DTCM1 lo bank 请求信号
logic                                                            dbank1_lo_req_vld_m1   ; // lo bank请求有效信号
logic                                                            dbank1_lo_req_rdy_m1   ; // lo bank请求就绪信号
logic [19:0]                                                     dbank1_lo_req_addr_m1  ; // lo bank请求地址（20位）
logic [TCM_ID_W-1:0]                                             dbank1_lo_req_id_m1    ; // lo bank请求ID
logic                                                            dbank1_lo_req_wr_m1    ; // lo bank写使能信号（0=读，1=写）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dbank1_lo_req_wdata_m1 ; // lo bank写数据
logic [3:0]                                                      dbank1_lo_req_wstrb_m1 ; // lo bank写选通信号（字节级使能）
logic [5:0]                                                      dbank1_lo_req_atop_m1  ; // lo bank原子操作码

// DTCM1 hi bank 请求信号
logic                                                            dbank1_hi_req_vld_m1   ; // hi bank请求有效信号
logic                                                            dbank1_hi_req_rdy_m1   ; // hi bank请求就绪信号
logic [19:0]                                                     dbank1_hi_req_addr_m1  ; // hi bank请求地址（20位）
logic [TCM_ID_W-1:0]                                             dbank1_hi_req_id_m1    ; // hi bank请求ID
logic                                                            dbank1_hi_req_wr_m1    ; // hi bank写使能信号（0=读，1=写）
logic [`CHUNJUN_DTCM_RAM_DATA_W-1:0]                             dbank1_hi_req_wdata_m1 ; // hi bank写数据
logic [3:0]                                                      dbank1_hi_req_wstrb_m1 ; // hi bank写选通信号（字节级使能）
logic [5:0]                                                      dbank1_hi_req_atop_m1  ; // hi bank原子操作码
//=================================================================================
// DTCM1 Bank 状态和控制信号
//=================================================================================
// 用于指示DTCM1各bank的工作状态和特殊操作模式

// 部分写和原子操作状态指示
logic                                                            dbank1_lo_into_partial_m1; // lo bank进入部分写状态
logic                                                            dbank1_hi_into_partial_m1; // hi bank进入部分写状态
logic                                                            dbank1_lo_into_atomic_m1; // lo bank进入原子操作状态
logic                                                            dbank1_hi_into_atomic_m1; // hi bank进入原子操作状态

// Bank忙闲状态指示
logic                                                            dbank1_lo_busy         ; // lo bank忙状态（正在处理请求）
logic                                                            dbank1_lo_idle         ; // lo bank空闲状态（可接受新请求）
logic                                                            dbank1_hi_busy         ; // hi bank忙状态（正在处理请求）
logic                                                            dbank1_hi_idle         ; // hi bank空闲状态（可接受新请求）

//=================================================================================
// DTCM1 Bank 保持寄存器和原子操作信号
//=================================================================================
// 用于DTCM1部分写和原子操作的数据保持

// 整体状态控制
logic                                                            dbank1_into_partial_m1 ; // DTCM1进入部分写状态
logic                                                            dbank1_into_atomic_m1  ; // DTCM1进入原子操作状态

// 保持数据控制信号
logic                                                            dbank1_hold_wdata_en   ; // 保持写数据使能
logic [63:0]                                                     dbank1_hold_wdata_m1   ; // 保持写数据（M1阶段）
logic                                                            dbank1_hold_wstrb_en   ; // 保持写选通使能
logic [7:0]                                                      dbank1_hold_wstrb_m1   ; // 保持写选通（M1阶段）

// 保持数据信号
logic [63:0]                                                     dbank1_hold_wdata      ; // 保持的写数据（64位）
logic [7:0]                                                      dbank1_hold_wstrb      ; // 保持的写选通（8位）

// 分解的保持数据信号
logic [31:0]                                                     dbank1_hold_wdata_lo   ; // 保持的写数据低32位
logic [31:0]                                                     dbank1_hold_wdata_hi   ; // 保持的写数据高32位
logic [3:0]                                                      dbank1_hold_wstrb_lo   ; // 保持的写选通低4位
logic [3:0]                                                      dbank1_hold_wstrb_hi   ; // 保持的写选通高4位

// 原子操作保持信号
logic [5:0]                                                      dbank1_lo_hold_atop_m1 ; // lo bank原子操作码保持（M1阶段）
logic [5:0]                                                      dbank1_hi_hold_atop_m1 ; // hi bank原子操作码保持（M1阶段）
logic [5:0]                                                      dbank1_hold_atop_lo    ; // 保持的原子操作码低32位
logic [5:0]                                                      dbank1_hold_atop_hi    ; // 保持的原子操作码高32位

// 原子操作比较信号
logic [31:0]                                                     dbank1_atop_cmp_val_m1 ; // 原子操作比较值（M1阶段）
logic [31:0]                                                     dbank1_hold_cmp_val    ; // 保持的原子操作比较值 

//=================================================================================
// DTCM1 lo Bank 响应信号
//=================================================================================
// DTCM1 lo bank的响应信号，包括M2、M3阶段和RAS报告

// DTCM1 lo bank响应信号（M2阶段）
logic                                                            dbank1_lo_rsp_vld_m2   ; // lo bank响应有效信号
logic [TCM_ID_W-1:0]                                             dbank1_lo_rsp_id_m2    ; // lo bank响应ID
logic [31:0]                                                     dbank1_lo_rsp_data_m2  ; // lo bank响应数据
logic                                                            dbank1_lo_rsp_se_m2    ; // lo bank单比特错误标志
logic                                                            dbank1_lo_rsp_de_m2    ; // lo bank双比特错误标志
logic [19:0]                                                     dbank1_lo_rsp_addr_m2  ; // lo bank响应地址

// DTCM1 lo bank响应信号（M3阶段）
logic                                                            dbank1_lo_rsp_vld_m3   ; // lo bank响应有效信号（M3阶段）
logic [TCM_ID_W-1:0]                                             dbank1_lo_rsp_id_m3    ; // lo bank响应ID（M3阶段）
logic [31:0]                                                     dbank1_lo_rsp_data_m3  ; // lo bank响应数据（M3阶段）
logic                                                            dbank1_lo_rsp_se_m3    ; // lo bank单比特错误标志（M3阶段）
logic                                                            dbank1_lo_rsp_de_m3    ; // lo bank双比特错误标志（M3阶段）
logic [19:0]                                                     dbank1_lo_rsp_addr_m3  ; // lo bank响应地址（M3阶段）

// DTCM1 lo bank原子操作状态信号
logic                                                            dbank1_lo_atop_b_infly_m3; // lo bank原子操作B阶段进行中（M3阶段）
logic                                                            dbank1_lo_atop_r_infly_m3; // lo bank原子操作R阶段进行中（M3阶段）

// DTCM1 lo bank RAS报告信号
logic                                                            dbank1_lo_rsp_vld_ras ; // lo bank RAS报告有效信号
logic [TCM_ID_W-1:0]                                             dbank1_lo_rsp_id_ras  ; // lo bank RAS报告ID
logic                                                            dbank1_lo_rsp_se_ras  ; // lo bank RAS报告单比特错误
logic                                                            dbank1_lo_rsp_de_ras  ; // lo bank RAS报告双比特错误
logic                                                            dbank1_lo_rsp_wr_ras  ; // lo bank RAS报告写操作标志
logic [19:0]                                                     dbank1_lo_rsp_addr_ras; // lo bank RAS报告地址
//=================================================================================
// DTCM1 hi Bank 响应信号
//=================================================================================
// DTCM1 hi bank的响应信号，包括M2、M3阶段和RAS报告

// DTCM1 hi bank响应信号（M2阶段）
logic                                                            dbank1_hi_rsp_vld_m2   ; // hi bank响应有效信号
logic [TCM_ID_W-1:0]                                             dbank1_hi_rsp_id_m2    ; // hi bank响应ID
logic [31:0]                                                     dbank1_hi_rsp_data_m2  ; // hi bank响应数据
logic                                                            dbank1_hi_rsp_se_m2    ; // hi bank单比特错误标志
logic                                                            dbank1_hi_rsp_de_m2    ; // hi bank双比特错误标志
logic [19:0]                                                     dbank1_hi_rsp_addr_m2  ; // hi bank响应地址

// DTCM1 hi bank响应信号（M3阶段）
logic                                                            dbank1_hi_rsp_vld_m3   ; // hi bank响应有效信号（M3阶段）
logic [TCM_ID_W-1:0]                                             dbank1_hi_rsp_id_m3    ; // hi bank响应ID（M3阶段）
logic [31:0]                                                     dbank1_hi_rsp_data_m3  ; // hi bank响应数据（M3阶段）
logic                                                            dbank1_hi_rsp_se_m3    ; // hi bank单比特错误标志（M3阶段）
logic                                                            dbank1_hi_rsp_de_m3    ; // hi bank双比特错误标志（M3阶段）
logic [19:0]                                                     dbank1_hi_rsp_addr_m3  ; // hi bank响应地址（M3阶段）

// DTCM1 hi bank原子操作状态信号
logic                                                            dbank1_hi_atop_b_infly_m3; // hi bank原子操作B阶段进行中（M3阶段）
logic                                                            dbank1_hi_atop_r_infly_m3; // hi bank原子操作R阶段进行中（M3阶段）

// DTCM1 hi bank RAS报告信号
logic                                                            dbank1_hi_rsp_vld_ras ; // hi bank RAS报告有效信号
logic [TCM_ID_W-1:0]                                             dbank1_hi_rsp_id_ras  ; // hi bank RAS报告ID
logic                                                            dbank1_hi_rsp_se_ras  ; // hi bank RAS报告单比特错误
logic                                                            dbank1_hi_rsp_de_ras  ; // hi bank RAS报告双比特错误
logic                                                            dbank1_hi_rsp_wr_ras  ; // hi bank RAS报告写操作标志
logic [19:0]                                                     dbank1_hi_rsp_addr_ras; // hi bank RAS报告地址

//=================================================================================
// VTCM支持信号（可选）
//=================================================================================
// 当CHUNJUN_SUPPORT_V_EXT宏定义时生效，用于向量TCM支持

`ifdef CHUNJUN_SUPPORT_V_EXT 
// VTCM请求ID对齐信号
logic [`CHUNJUN_VTCM_BANK_N-1:0][TCM_ID_W-1:0]                   aln_req_id_vtcm; // VTCM各bank对齐后的请求ID

// VTCM Bank请求接口信号（M1阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_req_vld_m1; // VTCM各bank请求有效信号
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_req_rdy_m1; // VTCM各bank请求就绪信号
logic [`CHUNJUN_VTCM_BANK_N-1:0][20-1:0]        vbank_req_addr_m1; // VTCM各bank请求地址（20位）
logic [`CHUNJUN_VTCM_BANK_N-1:0][TCM_ID_W-1:0]                   vbank_req_id_m1; // VTCM各bank请求ID
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_req_wr_m1; // VTCM各bank写使能信号（0=读，1=写）
logic [`CHUNJUN_VTCM_BANK_N-1:0][`CHUNJUN_VTCM_RAM_DATA_W-1:0]   vbank_req_wdata_m1; // VTCM各bank写数据
logic [`CHUNJUN_VTCM_BANK_N-1:0][3:0]                            vbank_req_wstrb_m1; // VTCM各bank写选通信号（字节级使能）
logic [`CHUNJUN_VTCM_BANK_N-1:0][1:0]                            vbank_req_dest_m1; // VTCM各bank请求目标（LSU/SBU/SLV）

// VTCM Bank状态和控制信号
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_into_partial_m1; // VTCM各bank进入部分写状态
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_busy; // VTCM各bank忙状态（正在处理请求）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_idle; // VTCM各bank空闲状态（可接受新请求）
 
// VTCM Bank响应信号（M2阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_vld_m2; // VTCM各bank响应有效信号
logic [`CHUNJUN_VTCM_BANK_N-1:0][TCM_ID_W-1:0]                   vbank_rsp_id_m2; // VTCM各bank响应ID
logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                           vbank_rsp_data_m2; // VTCM各bank响应数据
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_se_m2; // VTCM各bank单比特错误标志
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_de_m2; // VTCM各bank双比特错误标志
logic [`CHUNJUN_VTCM_BANK_N-1:0][1:0]                            vbank_rsp_data_dest_m2; // VTCM各bank响应数据目标（LSU/SBU/SLV）

// VTCM Bank响应信号（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0][19:0]                           vbank_rsp_addr_m2; // VTCM各bank响应地址（M2阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_vld_m3; // VTCM各bank响应有效信号（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0][TCM_ID_W-1:0]                   vbank_rsp_id_m3; // VTCM各bank响应ID（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                           vbank_rsp_data_m3; // VTCM各bank响应数据（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_se_m3; // VTCM各bank单比特错误标志（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_de_m3; // VTCM各bank双比特错误标志（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0][1:0]                            vbank_rsp_data_dest_m3; // VTCM各bank响应数据目标（M3阶段）
logic [`CHUNJUN_VTCM_BANK_N-1:0][19:0]                           vbank_rsp_addr_m3; // VTCM各bank响应地址（M3阶段）

// VTCM Bank RAS报告信号
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_vld_ras ; // VTCM各bank RAS报告有效信号
logic [`CHUNJUN_VTCM_BANK_N-1:0] [TCM_ID_W-1:0]                  vbank_rsp_id_ras  ; // VTCM各bank RAS报告ID
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_se_ras  ; // VTCM各bank RAS报告单比特错误
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_de_ras  ; // VTCM各bank RAS报告双比特错误
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_wr_ras  ; // VTCM各bank RAS报告写操作标志
logic [`CHUNJUN_VTCM_BANK_N-1:0] [19:0]                          vbank_rsp_addr_ras; // VTCM各bank RAS报告地址
 
// VTCM Bank保持寄存器信号
logic [`CHUNJUN_VTCM_BANK_N-1:0][31:0]                           vbank_hold_wdata; // VTCM各bank保持的写数据
logic [`CHUNJUN_VTCM_BANK_N-1:0][3:0]                            vbank_hold_wstrb; // VTCM各bank保持的写选通

// VTCM Bank优先级编码信号
logic [$clog2(`CHUNJUN_VTCM_BANK_N)-1:0]                         vbank_sbu_rsp_vld_first; // SBU响应有效bank的优先级编码
logic [$clog2(`CHUNJUN_VTCM_BANK_N)-1:0]                         vbank_slv_rsp_vld_first; // SLV响应有效bank的优先级编码

// VPU响应信号（M3阶段）
logic [5:0]                                                      vpu0_rsp_vld_m3; // VPU0响应有效信号（6位向量）
logic [5:0]                                                      vpu1_rsp_vld_m3; // VPU1响应有效信号（6位向量）
logic [5:0][31:0]                                                vpu_rsp_data_m3; // VPU响应数据（6个32位数据）
logic [5:0][`CHUNJUN_VLQID_W-1:0]                                vpu_rsp_id_m3  ; // VPU响应ID（6个ID）
logic [5:0]                                                      vpu_rsp_de_m3  ; // VPU双比特错误标志（6位向量）
`endif // CHUNJUN_SUPPORT_V_EXT
//=================================================================================
// VTCM Bank响应复用信号
//=================================================================================
// 用于VTCM各bank响应到不同主设备的复用和选择

// VTCM Bank响应有效信号（One-hot编码）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_lsu0_rsp_vld_m2_oh; // VTCM各bank到LSU0的响应有效（M2阶段，One-hot）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_lsu1_rsp_vld_m2_oh; // VTCM各bank到LSU1的响应有效（M2阶段，One-hot）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_lsu0_rsp_vld_m3_oh; // VTCM各bank到LSU0的响应有效（M3阶段，One-hot）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_lsu1_rsp_vld_m3_oh; // VTCM各bank到LSU1的响应有效（M3阶段，One-hot）

// VTCM Bank响应有效信号（向量编码）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_sbu_rsp_vld_m3_vec; // VTCM各bank到SBU的响应有效（M3阶段，向量）
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_slv_rsp_vld_m3_vec; // VTCM各bank到SLV的响应有效（M3阶段，向量）

// VTCM Bank到LSU的响应数据信号
logic [31:0]                                                     vbank_lsu0_rsp_data_m2; // VTCM到LSU0的响应数据（M2阶段）
logic [31:0]                                                     vbank_lsu1_rsp_data_m2; // VTCM到LSU1的响应数据（M2阶段）
logic [TCM_ID_W-1:0]                                             vbank_lsu0_rsp_id_m2; // VTCM到LSU0的响应ID（M2阶段）
logic [TCM_ID_W-1:0]                                             vbank_lsu1_rsp_id_m2; // VTCM到LSU1的响应ID（M2阶段）
logic [TCM_ID_W-1:0]                                             vbank_lsu0_rsp_id_m3; // VTCM到LSU0的响应ID（M3阶段）
logic [TCM_ID_W-1:0]                                             vbank_lsu1_rsp_id_m3; // VTCM到LSU1的响应ID（M3阶段）

// VTCM Bank到LSU的错误标志信号
logic                                                            vbank_lsu0_rsp_se_m3; // VTCM到LSU0的单比特错误标志（M3阶段）
logic                                                            vbank_lsu1_rsp_se_m3; // VTCM到LSU1的单比特错误标志（M3阶段）
logic                                                            vbank_lsu0_rsp_de_m3; // VTCM到LSU0的双比特错误标志（M3阶段）
logic                                                            vbank_lsu1_rsp_de_m3; // VTCM到LSU1的双比特错误标志（M3阶段）

// VTCM Bank到SBU/SLV的响应信号
logic [TCM_ID_W-1:0]                                             vbank_sbu_rsp_id_m3; // VTCM到SBU的响应ID（M3阶段）
logic                                                            vbank_sbu_rsp_de_m3; // VTCM到SBU的双比特错误标志（M3阶段）
logic [TCM_ID_W-1:0]                                             vbank_slv_rsp_id_m3; // VTCM到SLV的响应ID（M3阶段）
logic                                                            vbank_slv_rsp_de_m3; // VTCM到SLV的双比特错误标志（M3阶段）
logic [63:0]                                                     vbank_slv_rsp_data_m3; // VTCM到SLV的响应数据（M3阶段）
 
//=================================================================================
// ICU响应信号
//=================================================================================
// ICU的响应信号，包括M2和M3阶段

// ICU响应信号（M2阶段）
logic [2:0]                                                      icu_rsp_vld_m2 ; // ICU响应有效信号（3位向量）
logic [2:0][63:0]                                                icu_rsp_data_m2; // ICU响应数据（3个64位数据）
logic [2:0][$clog2(4)-1:0]                              icu_rsp_id_m2  ; // ICU响应ID（3个ID）

// ICU响应信号（M3阶段）
logic [2:0]                                                      icu_rsp_vld_m3 ; // ICU响应有效信号（M3阶段，3位向量）
logic [2:0][$clog2(4)-1:0]                              icu_rsp_id_m3  ; // ICU响应ID（M3阶段，3个ID）
logic [2:0]                                                      icu_rsp_se_m3  ; // ICU单比特错误标志（M3阶段，3位向量）
logic [2:0]                                                      icu_rsp_de_m3  ; // ICU双比特错误标志（M3阶段，3位向量）

//=================================================================================
// LSU响应信号
//=================================================================================
// LSU0/1的响应信号，包括M2和M3阶段

// LSU响应信号（M2阶段）
logic [6:0]                                                      lsu0_rsp_vld_m2 ; // LSU0响应有效信号（7位向量）
logic [6:0]                                                      lsu1_rsp_vld_m2 ; // LSU1响应有效信号（7位向量）
logic [6:0][31:0]                                                lsu0_rsp_data_m2; // LSU0响应数据（7个32位数据）
logic [6:0][31:0]                                                lsu1_rsp_data_m2; // LSU1响应数据（7个32位数据）
logic [6:0][($clog2(6) + 1)-1:0]                                lsu0_rsp_id_m2  ; // LSU0响应ID（7个ID）
logic [6:0][($clog2(6) + 1)-1:0]                                lsu1_rsp_id_m2  ; // LSU1响应ID（7个ID）

// LSU响应信号（M3阶段）
logic [6:0]                                                      lsu0_rsp_vld_m3 ; // LSU0响应有效信号（M3阶段，7位向量）
logic [6:0]                                                      lsu1_rsp_vld_m3 ; // LSU1响应有效信号（M3阶段，7位向量）
logic [6:0][($clog2(6) + 1)-1:0]                                lsu0_rsp_id_m3  ; // LSU0响应ID（M3阶段，7个ID）
logic [6:0][($clog2(6) + 1)-1:0]                                lsu1_rsp_id_m3  ; // LSU1响应ID（M3阶段，7个ID）

// LSU错误标志信号（M3阶段）
logic [6:0]                                                      lsu0_rsp_se_m3 ; // LSU0单比特错误标志（M3阶段，7位向量）
logic [6:0]                                                      lsu1_rsp_se_m3 ; // LSU1单比特错误标志（M3阶段，7位向量）
logic [6:0]                                                      lsu0_rsp_de_m3 ; // LSU0双比特错误标志（M3阶段，7位向量）
logic [6:0]                                                      lsu1_rsp_de_m3 ; // LSU1双比特错误标志（M3阶段，7位向量）
 
//=================================================================================
// SBU响应信号（M3阶段）
//=================================================================================
// SBU的响应信号，包括基本响应和原子操作响应

// SBU基本响应信号
logic [3:0]                                                      sbu_rsp_vld_m3 ; // SBU响应有效信号（4位向量）
logic [3:0][$clog2(6)-1:0]                            sbu_rsp_id_m3  ; // SBU响应ID（4个ID）
logic [$clog2(6)-1:0]                                 sbu_rsp_id_mux  ; // SBU响应ID复用信号
logic [3:0]                                                      sbu_rsp_de_m3 ; // SBU双比特错误标志（4位向量）
logic                                                            sbu_rsp_de_mux ; // SBU双比特错误标志复用信号

// SBU原子操作响应信号
logic [3:0]                                                      sbu_atop_bvld_m3 ; // SBU原子操作B阶段有效信号（4位向量）
logic [3:0]                                                      sbu_atop_rvld_m3 ; // SBU原子操作R阶段有效信号（4位向量）
logic [3:0][31:0]                                                sbu_atop_rdata_m3; // SBU原子操作读数据（4个32位数据）
logic [3:0][$clog2(6)-1:0]                            sbu_atop_id_m3; // SBU原子操作ID（4个ID）
logic [3:0]                                                      sbu_atop_de_m3; // SBU原子操作双比特错误标志（4位向量）

//=================================================================================
// SLV响应信号（M3阶段）
//=================================================================================
// SLV的响应信号

logic [3:0]                                                      slv_rsp_vld_m3 ; // SLV响应有效信号（4位向量）
logic [3:0][63:0]                                                slv_rsp_data_m3; // SLV响应数据（4个64位数据）
logic [3:0][(8 + 2 + 3)-1:0]                         slv_rsp_id_m3  ; // SLV响应ID（4个ID）
logic [3:0]                                                      slv_rsp_de_m3  ; // SLV双比特错误标志（4位向量）
 
//=================================================================================
// BMU响应信号
//=================================================================================
// BMU的响应信号，包括预处理和接收控制

// BMU响应预处理信号
logic [63:0]                                                     bmu_rsp_data_pre  ; // BMU响应数据预处理信号（64位）
logic [(8 + 2 + 3)-1:0]                              bmu_rsp_id_pre    ; // BMU响应ID预处理信号
logic                                                            bmu_rsp_raserr_pre; // BMU RAS错误预处理信号

// BMU响应接收控制信号
logic                                                            bmu_rsp_rcv_hi    ; // BMU响应接收高64位标志
logic                                                            bmu_rsp_rcv_lo_set; // BMU响应接收低64位设置标志
logic                                                            bmu_rsp_rcv_lo_clr; // BMU响应接收低64位清除标志
logic                                                            bmu_rsp_rcv_lo_en ; // BMU响应接收低64位使能
logic                                                            bmu_rsp_rcv_lo_d  ; // BMU响应接收低64位（组合逻辑）
logic                                                            bmu_rsp_rcv_lo_q  ; // BMU响应接收低64位（寄存器）

// BMU响应接收数据信号
logic [63:0]                                                     bmu_rsp_rcv_data_lo; // BMU响应接收低64位数据
logic                                                            bmu_rsp_rcv_raserr_lo; // BMU响应接收低64位RAS错误

//=================================================================================
// ITCM RAS报告信号
//=================================================================================
// ITCM的RAS（可靠性、可用性、可服务性）报告信号

logic [4:0]                                                      itcm_req_src_ras; // ITCM请求源RAS信号（5位向量）

//=================================================================================
// DTCM0 RAS报告信号
//=================================================================================
// DTCM0的RAS报告信号，包括错误聚合和优先级选择

// DTCM0请求源和错误向量信号
logic [4:0]                                                      dtcm0_req_src_ras; // DTCM0请求源RAS信号（5位向量）
logic [1:0]                                                      dtcm0_rsp_se_ras_vec; // DTCM0单比特错误向量（2位向量）
logic [1:0]                                                      dtcm0_rsp_de_ras_vec; // DTCM0双比特错误向量（2位向量）

// DTCM0错误优先级选择信号
logic [1:0]                                                      dtcm0_rsp_se_oh; // DTCM0单比特错误One-hot选择（2位向量）
logic [1:0]                                                      dtcm0_rsp_de_oh; // DTCM0双比特错误One-hot选择（2位向量）
logic [1:0]                                                      dtcm0_rsp_ras_oh; // DTCM0 RAS错误One-hot选择（2位向量）

// DTCM0 RAS报告字段信号
logic [TCM_ID_W-1:0]                                             dtcm0_ras_id; // DTCM0 RAS报告ID
logic                                                            dtcm0_ras_wr; // DTCM0 RAS报告写操作标志
logic [19:0]                                                     dtcm0_ras_addr_offs; // DTCM0 RAS报告地址偏移
//=================================================================================
// DTCM1 RAS报告信号
//=================================================================================
// DTCM1的RAS报告信号，包括错误聚合和优先级选择

// DTCM1请求源和错误向量信号
logic [4:0]                                                      dtcm1_req_src_ras; // DTCM1请求源RAS信号（5位向量）
logic [1:0]                                                      dtcm1_rsp_se_ras_vec; // DTCM1单比特错误向量（2位向量）
logic [1:0]                                                      dtcm1_rsp_de_ras_vec; // DTCM1双比特错误向量（2位向量）

// DTCM1错误优先级选择信号
logic [1:0]                                                      dtcm1_rsp_se_oh; // DTCM1单比特错误One-hot选择（2位向量）
logic [1:0]                                                      dtcm1_rsp_de_oh; // DTCM1双比特错误One-hot选择（2位向量）
logic [1:0]                                                      dtcm1_rsp_ras_oh; // DTCM1 RAS错误One-hot选择（2位向量）

// DTCM1 RAS报告字段信号
logic [TCM_ID_W-1:0]                                             dtcm1_ras_id; // DTCM1 RAS报告ID
logic                                                            dtcm1_ras_wr; // DTCM1 RAS报告写操作标志
logic [19:0]                                                     dtcm1_ras_addr_offs; // DTCM1 RAS报告地址偏移
//=================================================================================
// VTCM RAS报告信号
//=================================================================================
// VTCM的RAS报告信号，包括错误聚合和优先级选择

// VTCM错误向量信号
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_se_vec; // VTCM各bank单比特错误向量
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_de_vec; // VTCM各bank双比特错误向量

// VTCM错误优先级选择信号
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_se_oh; // VTCM单比特错误One-hot选择
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vbank_rsp_de_oh; // VTCM双比特错误One-hot选择
logic [`CHUNJUN_VTCM_BANK_N-1:0]                                 vtcm_rsp_ras_oh; // VTCM RAS错误One-hot选择

// VTCM RAS报告字段信号
logic [TCM_ID_W-1:0]                                             vtcm_ras_id; // VTCM RAS报告ID
logic                                                            vtcm_ras_wr; // VTCM RAS报告写操作标志
logic [19:0]                                                     vtcm_ras_addr_offs; // VTCM RAS报告地址偏移
logic [3:0]                                                      vtcm_req_src_ras; // VTCM请求源RAS信号（4位向量）

//=================================================================================
// 1xN Router
//=================================================================================

//----------------------------
// icu router to each TCM
//----------------------------
// ICU cannot access VTCM
assign icu_iarb_req_vld  = icu_tcu_req_vld_m1 & icu_tcu_req_route_m1[0];  //通过req_route_m1[0]的信号选择目标ITCM
assign icu_dtcm0_req_vld = icu_tcu_req_vld_m1 & icu_tcu_req_route_m1[1];  //通过req_route_m1[1]的信号选择目标DTCM0
assign icu_dtcm1_req_vld = icu_tcu_req_vld_m1 & icu_tcu_req_route_m1[2];  //通过req_route_m1[2]的信号选择目标DTCM1

assign tcu_icu_req_rdy_m1 = iarb_icu_req_rdy | dtcm0_icu_req_rdy | dtcm1_icu_req_rdy;  //ITCM和DTCM0/DTCM1 给 ICU 的响应

//----------------------------
// ld0 router to each TCM
//----------------------------
assign lsu_ld0_iarb_req_vld = lsu_tcu_ld_req_valid_m1[0] & lsu_tcu_ld_req_route_m1[0][0]; //LSU Load0 到 ITCM 的路由选择
assign lsu_dtcm0_req_vld[0] = lsu_tcu_ld_req_valid_m1[0] & lsu_tcu_ld_req_route_m1[0][1]; //LSU Load0 到 DTCM0 的路由选择
assign lsu_dtcm1_req_vld[0] = lsu_tcu_ld_req_valid_m1[0] & lsu_tcu_ld_req_route_m1[0][2]; //LSU Load0 到 DTCM1 的路由选择
assign lsu_vtcm_req_vld[0]  = lsu_tcu_ld_req_valid_m1[0] & lsu_tcu_ld_req_route_m1[0][3]; //LSU Load0 到 VTCM 的路由选择

assign tcu_lsu_ld_req_ready_m1[0] = iarb_lsu0_req_rdy | dtcm0_lsu_req_rdy[0] | dtcm1_lsu_req_rdy[0] | vtcm_lsu_req_rdy[0]; //ITCM和DTCM0/DTCM1 给 LSU Load0 的响应

//----------------------------
// ld1 router to each TCM
//----------------------------
assign lsu_ld1_iarb_req_vld = lsu_tcu_ld_req_valid_m1[1] & lsu_tcu_ld_req_route_m1[1][0]; //LSU Load1 到 ITCM 的路由选择
assign lsu_dtcm0_req_vld[1] = lsu_tcu_ld_req_valid_m1[1] & lsu_tcu_ld_req_route_m1[1][1]; //LSU Load1 到 DTCM0 的路由选择
assign lsu_dtcm1_req_vld[1] = lsu_tcu_ld_req_valid_m1[1] & lsu_tcu_ld_req_route_m1[1][2]; //LSU Load1 到 DTCM1 的路由选择
assign lsu_vtcm_req_vld[1]  = lsu_tcu_ld_req_valid_m1[1] & lsu_tcu_ld_req_route_m1[1][3]; //LSU Load1 到 VTCM 的路由选择

assign tcu_lsu_ld_req_ready_m1[1] = iarb_lsu1_req_rdy | dtcm0_lsu_req_rdy[1] | dtcm1_lsu_req_rdy[1] | vtcm_lsu_req_rdy[1]; //ITCM和DTCM0/DTCM1 给 LSU Load1 的响应

//----------------------------
// sbu router to each TCM
//----------------------------
assign sbu_iarb_req_vld  = sbu_tcu_req_vld & sbu_tcu_req_route[0]; //SBU 到 ITCM 的路由选择
assign sbu_dtcm0_req_vld = sbu_tcu_req_vld & sbu_tcu_req_route[1]; //SBU 到 DTCM0 的路由选择
assign sbu_dtcm1_req_vld = sbu_tcu_req_vld & sbu_tcu_req_route[2]; //SBU 到 DTCM1 的路由选择
assign sbu_vtcm_req_vld  = sbu_tcu_req_vld & sbu_tcu_req_route[3]; //SBU 到 VTCM 的路由选择

assign tcu_sbu_req_rdy = iarb_sbu_req_rdy | dtcm0_sbu_req_rdy | dtcm1_sbu_req_rdy | vtcm_sbu_req_rdy; //ITCM和DTCM0/DTCM1 给 SBU 的响应

//----------------------------
// bmu router to each TCM
//----------------------------
assign slv_iarb_req_vld  = bmu_req_vld_mux & bmu_req_route_mux[0]; //SLV 到 ITCM 的路由选择
assign slv_dtcm0_req_vld = bmu_req_vld_mux & bmu_req_route_mux[1]; //SLV 到 DTCM0 的路由选择
assign slv_dtcm1_req_vld = bmu_req_vld_mux & bmu_req_route_mux[2]; //SLV 到 DTCM1 的路由选择
assign slv_vtcm_req_vld  = bmu_req_vld_mux & bmu_req_route_mux[3]; //SLV 到 VTCM 的路由选择

assign slv_req_grt = iarb_slv_req_rdy | dtcm0_slv_req_rdy | dtcm1_slv_req_rdy | vtcm_slv_req_rdy; //ITCM和DTCM0/DTCM1 给 SLV 的响应
 
assign tcu_bmu_req_rdy = slv_req_grt & bmu_req_buf_empty; //SLV 的响应， 如果SLV的请求被缓冲区接收，并且缓冲区为空（tie0），则SLV的响应为1

//**********************************************************************************************//
`ifdef CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//
//----------------------------
// vpu ld0 router to each TCM
//----------------------------
assign vpu_ld0_iarb_req_vld = vpu_tcu_ld_req_vld_m1[0] & vpu_tcu_ld_req_route_m1[0][0]; //VPU0 到 ITCM 的路由选择
assign vpu_dtcm0_req_vld[0] = vpu_tcu_ld_req_vld_m1[0] & vpu_tcu_ld_req_route_m1[0][1]; //VPU0 到 DTCM0 的路由选择
assign vpu_dtcm1_req_vld[0] = vpu_tcu_ld_req_vld_m1[0] & vpu_tcu_ld_req_route_m1[0][2]; //VPU0 到 DTCM1 的路由选择

assign tcu_vpu_ld_req_rdy_m1[0] = iarb_vpu0_req_rdy | dtcm0_vpu_req_rdy[0] | dtcm1_vpu_req_rdy[0]; //ITCM和DTCM0/DTCM1 给 VPU0 的响应
 
assign vpu_dtcm0_req_addr = vpu_tcu_ld_req_addr_m1; //VPU0 到 DTCM0 的地址

//----------------------------
// vpu ld1 router to each TCM
//----------------------------
assign vpu_ld1_iarb_req_vld = vpu_tcu_ld_req_vld_m1[1] & vpu_tcu_ld_req_route_m1[1][0]; //VPU1 到 ITCM 的路由选择
assign vpu_dtcm0_req_vld[1] = vpu_tcu_ld_req_vld_m1[1] & vpu_tcu_ld_req_route_m1[1][1]; //VPU1 到 DTCM0 的路由选择
assign vpu_dtcm1_req_vld[1] = vpu_tcu_ld_req_vld_m1[1] & vpu_tcu_ld_req_route_m1[1][2]; //VPU1 到 DTCM1 的路由选择

assign tcu_vpu_ld_req_rdy_m1[1] = iarb_vpu1_req_rdy | dtcm0_vpu_req_rdy[1] | dtcm1_vpu_req_rdy[1]; //ITCM和DTCM0/DTCM1 给 VPU1 的响应
 
assign vpu_dtcm1_req_addr = vpu_tcu_ld_req_addr_m1; //VPU1 到 DTCM1 的地址
//**********************************************************************************************//
`else // CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//
assign vpu_ld0_iarb_req_vld = 1'b0; //当不支持VPU时，VPU0 到 ITCM 的路由选择为0
assign vpu_dtcm0_req_vld[0] = 1'b0; //当不支持VPU时，VPU0 到 DTCM0 的路由选择为0
assign vpu_dtcm1_req_vld[0] = 1'b0; //当不支持VPU时，VPU0 到 DTCM1 的路由选择为0

assign vpu_ld1_iarb_req_vld = 1'b0; //当不支持VPU时，VPU1 到 ITCM 的路由选择为0
assign vpu_dtcm0_req_vld[1] = 1'b0; //当不支持VPU时，VPU1 到 DTCM0 的路由选择为0
assign vpu_dtcm1_req_vld[1] = 1'b0; //当不支持VPU时，VPU1 到 DTCM1 的路由选择为0

assign vpu_dtcm0_req_addr = '0; //当不支持VPU时，VPU0 到 DTCM0 的地址为0
assign vpu_dtcm1_req_addr = '0; //当不支持VPU时，VPU1 到 DTCM1 的地址为0
//**********************************************************************************************//
`endif //CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//

//=================================================================================
// Pre-Process
//=================================================================================

//----------------------------
//      ID Extension
//----------------------------
// 对齐请求ID，确保每个请求的ID长度一致
assign aln_req_id_icu    = {EXT_ID_ICU , {TCM_ID_IM_W-$clog2(4)     {1'b0}}, icu_tcu_req_id_m1         };   //对齐ICU请求ID
assign aln_req_id_lsu[0] = {EXT_ID_LSU0, {TCM_ID_IM_W-($clog2(6) + 1)       {1'b0}}, lsu_tcu_ld_req_lsqid_m1[0]}; //对齐LSU0请求ID
assign aln_req_id_lsu[1] = {EXT_ID_LSU1, {TCM_ID_IM_W-($clog2(6) + 1)       {1'b0}}, lsu_tcu_ld_req_lsqid_m1[1]}; //对齐LSU1请求ID
assign aln_req_id_sbu    = {EXT_ID_SBU , {TCM_ID_IM_W-$clog2(6)   {1'b0}}, sbu_tcu_req_id            };   //对齐SBU请求ID
assign aln_req_id_slv    = {EXT_ID_SLV , {TCM_ID_IM_W-(8 + 2 + 3){1'b0}}, bmu_req_id_mux            };   //对齐SLV请求ID
 
//拓展VPU的ID
`ifdef CHUNJUN_SUPPORT_V_EXT
assign aln_req_id_vpu[0] = {EXT_ID_VPU0, {TCM_ID_IM_W-`CHUNJUN_VLQID_W       {1'b0}}, vpu_tcu_ld_req_vlqid_m1[0]}; //对齐VPU0请求ID
assign aln_req_id_vpu[1] = {EXT_ID_VPU1, {TCM_ID_IM_W-`CHUNJUN_VLQID_W       {1'b0}}, vpu_tcu_ld_req_vlqid_m1[1]}; //对齐VPU1请求ID

for(genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_id_aln
  assign aln_req_id_vtcm[i] = {EXT_ID_VTCM, {TCM_ID_IM_W-1-`CHUNJUN_VLQID_W{1'b0}}, vpu_vtcu_req_info_m1[i]}; //对齐VTCM请求ID
end
`else //CHUNJUN_SUPPORT_V_EXT
assign aln_req_id_vpu[0] = {TCM_ID_W{1'b0}}; //不支持VPU时，VPU0请求ID为0
assign aln_req_id_vpu[1] = {TCM_ID_W{1'b0}}; //不支持VPU时，VPU1请求ID为0
`endif //CHUNJUN_SUPPORT_V_EXT

//----------------------------
//        VPU cancel
//----------------------------
`ifdef CHUNJUN_SUPPORT_V_EXT
assign vpu_tcu_cancel_m2 = vpu_tcu_ld_req_cancel_m2;
`else  // CHUNJUN_SUPPORT_V_EXT
assign vpu_tcu_cancel_m2 = 1'b0;
`endif // CHUNJUN_SUPPORT_V_EXT

//----------------------------
//        ATOP wdata
//----------------------------
// wdata of atop always stay in wdata[31:0]
// if not support A_ext, sbu_tcu_req_atop = '0
assign sbu_req_wdata_atop_mux = (|sbu_tcu_req_atop) ? {sbu_tcu_req_wdata[31:0],sbu_tcu_req_wdata[31:0]} : sbu_tcu_req_wdata; //如果支持A_ext，则将wdata[31:0]复制到wdata[63:32]，否则使用wdata[63:0]

//----------------------------
//        ECC Encode 
//----------------------------
// Ecode the wdata before arbiter, benefit for timing
//**********************************************************************************************//
`ifdef CHUNJUN_SUPPORT_MEM_ECC
//**********************************************************************************************//
wing_cbb_ecc_enc32 u_sbu_lo_enc_32(.data_i(sbu_req_wdata_atop_mux[31: 0]), .enc_o(enc_code_sbu_lo)); // sbu原子操作低32位数据编码
wing_cbb_ecc_enc32 u_sbu_hi_enc_32(.data_i(sbu_req_wdata_atop_mux[63:32]), .enc_o(enc_code_sbu_hi)); // sbu原子操作高32位数据编码
wing_cbb_ecc_enc64 u_sbu_enc_64   (.data_i(sbu_req_wdata_atop_mux       ), .enc_o(enc_code_sbu_64)); // sbu原子操作64位数据编码
 
wing_cbb_ecc_enc32 u_bmu_lo_enc_32(.data_i(bmu_req_wdata_mux[31: 0]     ), .enc_o(enc_code_bmu_lo)); // bmu低32位数据编码
wing_cbb_ecc_enc32 u_bmu_hi_enc_32(.data_i(bmu_req_wdata_mux[63:32]     ), .enc_o(enc_code_bmu_hi)); // bmu高32位数据编码
wing_cbb_ecc_enc64 u_bmu_enc_64   (.data_i(bmu_req_wdata_mux            ), .enc_o(enc_code_bmu_64)); // bmu64位数据编码
// 32位访问粒度数据（用于DTCM0/DTCM1）- 两个32位bank
assign sbu_wdata_post_enc_lo = {enc_code_sbu_lo      , sbu_req_wdata_atop_mux[31: 0]}; // sbu原子操作低32位数据校验码与原数据拼接
assign sbu_wdata_post_enc_hi = {enc_code_sbu_hi      , sbu_req_wdata_atop_mux[63:32]}; // sbu原子操作高32位数据校验码与原数据拼接
assign bmu_wdata_post_enc_lo = {enc_code_bmu_lo      , bmu_req_wdata_mux[31: 0]     }; // bmu低32位数据校验码与原数据拼接
assign bmu_wdata_post_enc_hi = {enc_code_bmu_hi      , bmu_req_wdata_mux[63:32]     }; // bmu高32位数据校验码与原数据拼接
// 64位访问粒度数据（用于ITCM）- 单一64位bank
assign sbu_wdata_post_enc_32 = {sbu_wdata_post_enc_hi, sbu_wdata_post_enc_lo }; // 78位：高39位 + 低39位
assign sbu_wdata_post_enc_64 = {enc_code_sbu_64      , sbu_req_wdata_atop_mux}; // 72位：8位校验码 + 64位数据
assign bmu_wdata_post_enc_32 = {bmu_wdata_post_enc_hi, bmu_wdata_post_enc_lo }; // 78位：高39位 + 低39位
assign bmu_wdata_post_enc_64 = {enc_code_bmu_64      , bmu_req_wdata_mux     }; // 72位：8位校验码 + 64位数据

//----------------------------
//      DTCM Wdata MUX
//----------------------------
assign sbu_dtcm_wdata = sbu_wdata_post_enc_32; //sbu给DTCM0/DTCM1 的写数据， 78位：高39位 + 低39位
assign bmu_dtcm_wdata = bmu_wdata_post_enc_32; //bmu给DTCM0/DTCM1 的写数据， 78位：高39位 + 低39位
`else  // CHUNJUN_SUPPORT_MEM_ECC
assign sbu_dtcm_wdata = sbu_req_wdata_atop_mux; //sbu给DTCM0/DTCM1 的写数据， 64位：64位数据
assign bmu_dtcm_wdata = bmu_req_wdata_mux; //bmu给DTCM0/DTCM1 的写数据， 64位：64位数据
`endif // CHUNJUN_SUPPORT_MEM_ECC

//----------------------------
//      S-BUS Req Buffer
//----------------------------
// If SBUS DATA_W = 128-bit, split 128-bit req into 2 64-bit req
// store the req info, and generate 2 64-bit req
assign bmu_tcu_req_hdsk = bmu_tcu_req_vld & tcu_bmu_req_rdy;

if (`CHUNJUN_MBUS_DATA_W == 128) begin: g_bmu_req_buffer
 
assign bmu_req_buf_empty = ~bmu_req_buf_vld_q;  //nouse
assign bmu_req_hi_sent   = slv_req_grt & bmu_req_buf_vld_q; //nouse

assign bmu_req_buf_vld_set = bmu_tcu_req_hdsk;//nouse
assign bmu_req_buf_vld_clr = bmu_req_hi_sent;//nouse
assign bmu_req_buf_vld_en  = bmu_req_buf_vld_set | bmu_req_buf_vld_clr;//nouse
assign bmu_req_buf_vld_d   = bmu_req_buf_vld_set;//nouse
 
assign bmu_req_info_en     = bmu_tcu_req_hdsk; //nouse

assign bmu_req_buf_addr_d  = bmu_tcu_req_addr;//nouse
assign bmu_req_buf_route_d = bmu_tcu_req_route;//nouse
assign bmu_req_buf_wr_d    = bmu_tcu_req_wr;//nouse
assign bmu_req_buf_wdata_d = bmu_tcu_req_wdata[127:64];//nouse
assign bmu_req_buf_wstrb_d = bmu_tcu_req_wstrb[15:8];//nouse
assign bmu_req_buf_id_d    = bmu_tcu_req_id;//nouse

`WDFFER(bmu_req_buf_vld_q  , bmu_req_buf_vld_d  , bmu_req_buf_vld_en, clk, rst_n)//nouse
`WDFFER(bmu_req_buf_addr_q , bmu_req_buf_addr_d , bmu_req_info_en   , clk, rst_n)//nouse
`WDFFER(bmu_req_buf_route_q, bmu_req_buf_route_d, bmu_req_info_en   , clk, rst_n)//nouse
`WDFFER(bmu_req_buf_wr_q   , bmu_req_buf_wr_d   , bmu_req_info_en   , clk, rst_n)//nouse
`WDFFER(bmu_req_buf_wdata_q, bmu_req_buf_wdata_d, bmu_req_info_en   , clk, rst_n)//nouse
`WDFFER(bmu_req_buf_wstrb_q, bmu_req_buf_wstrb_d, bmu_req_info_en   , clk, rst_n)//nouse
`WDFFER(bmu_req_buf_id_q   , bmu_req_buf_id_d   , bmu_req_info_en   , clk, rst_n)//nouse
 
assign bmu_req_wdata_lo = bmu_tcu_req_wdata[63:0];//nouse
assign bmu_req_wdata_hi = bmu_req_buf_wdata_q;//nouse

assign bmu_req_wstrb_lo = bmu_tcu_req_wstrb[7:0];//nouse
assign bmu_req_wstrb_hi = bmu_req_buf_wstrb_q;//nouse
 
assign bmu_req_addr_lo  = {bmu_tcu_req_addr[20-1:4],   4'b0000};//nouse
assign bmu_req_addr_hi  = {bmu_req_buf_addr_q[20-1:4], 4'b1000};//nouse
 
assign bmu_req_vld_mux   = bmu_tcu_req_vld | bmu_req_buf_vld_q;
assign bmu_req_addr_mux  = bmu_req_buf_empty ? bmu_req_addr_lo   : bmu_req_addr_hi;//nouse
assign bmu_req_route_mux = bmu_req_buf_empty ? bmu_tcu_req_route : bmu_req_buf_route_q;//nouse
assign bmu_req_wr_mux    = bmu_req_buf_empty ? bmu_tcu_req_wr    : bmu_req_buf_wr_q;//nouse
assign bmu_req_wdata_mux = bmu_req_buf_empty ? bmu_req_wdata_lo  : bmu_req_wdata_hi;//nouse
assign bmu_req_wstrb_mux = bmu_req_buf_empty ? bmu_req_wstrb_lo  : bmu_req_wstrb_hi;//nouse
assign bmu_req_id_mux    = bmu_req_buf_empty ? bmu_tcu_req_id    : bmu_req_buf_id_q;//nouse

end else if(`CHUNJUN_MBUS_DATA_W == 64) begin: g_bmu_req_through
//=================================================================================
// BMU 64位数据宽度直通模式
//=================================================================================
// 当系统总线数据宽度为64位时，BMU请求可以直接通过，无需拆分和缓冲
// 因为64位数据宽度与TCM内部数据宽度匹配，无需额外的数据对齐处理

// 缓冲区状态指示：64位模式下缓冲区始终为空（无需缓冲）
assign bmu_req_buf_empty = 1'b1;  // 缓冲区空标志，64位模式下始终为1（无缓冲需求）

// 请求信号直通：直接将BMU输入信号连接到复用器输出
assign bmu_req_vld_mux   = bmu_tcu_req_vld;    // 请求有效信号直通
assign bmu_req_addr_mux  = {bmu_tcu_req_addr[20-1:3], 3'b000}; // 地址对齐：低3位清零，确保8字节对齐
assign bmu_req_route_mux = bmu_tcu_req_route;  // 路由信息直通（指示访问目标：ITCM/DTCM/VTCM）
assign bmu_req_wr_mux    = bmu_tcu_req_wr;     // 写使能信号直通（0=读操作，1=写操作）
assign bmu_req_wdata_mux = bmu_tcu_req_wdata;  // 写数据直通（64位数据）
assign bmu_req_wstrb_mux = bmu_tcu_req_wstrb;  // 写选通信号直通（字节级写使能）
assign bmu_req_id_mux    = bmu_tcu_req_id;     // 请求ID直通（用于响应匹配）

end

//=================================================================================
// CSR ECC 错误注入控制寄存器解析
//=================================================================================
// 功能：从PCU CSR寄存器中提取ECC错误注入的控制参数
// 用途：用于测试和验证ECC检测和纠正功能的正确性

// 全局控制信号
assign csr_ecc_en         = pcu_csr_msyscfg[3];       // 全局ECC使能位：控制整个TCM的ECC功能开关
assign csr_inject_en      = pcu_csr_meictl[0];        // ECC错误注入使能：控制是否启用错误注入功能

// 注入目标选择：4位编码指定要注入错误的TCM类型
assign csr_inject_dest    = pcu_csr_meictl[4:1];      // 注入目标编码：
                                                       // 0100: ITCM（指令TCM）
                                                       // 0101: DTCM0（数据TCM0）
                                                       // 0110: DTCM1（数据TCM1）
                                                       // 0111: VTCM（向量TCM）

// 注入位置控制
assign csr_inject_bank    = pcu_csr_meictl[8:5];      // Bank选择位：指定要注入错误的bank
                                                       // 对于ITCM/DTCM：bank[0]选择低/高32位
                                                       // 对于VTCM：使用i/2映射选择bank组

// 错误注入掩码：定义要翻转的位位置
assign csr_inject_bitmapl = pcu_csr_meibmap;          // 低32位注入掩码：指定低半字中要翻转的位
assign csr_inject_bitmaph = pcu_csr_meibmaph;         // 高32位注入掩码：指定高半字中要翻转的位

//=================================================================================
// 各TCM错误注入使能信号生成
//=================================================================================
// 每个TCM的注入使能 = 全局ECC使能 & 注入使能 & 目标匹配 & bank选择
assign ecc_inject_itcm  = csr_ecc_en & csr_inject_en & (csr_inject_dest == 4'b0100) & csr_inject_bank[0]; // ITCM注入：使用bank[0]选择低/高64位
assign ecc_inject_dtcm0 = csr_ecc_en & csr_inject_en & (csr_inject_dest == 4'b0101) & csr_inject_bank[0]; // DTCM0注入：使用bank[0]选择低/高32位
assign ecc_inject_dtcm1 = csr_ecc_en & csr_inject_en & (csr_inject_dest == 4'b0110) & csr_inject_bank[0]; // DTCM1注入：使用bank[0]选择低/高32位
assign ecc_inject_vtcm  = csr_ecc_en & csr_inject_en & (csr_inject_dest == 4'b0111);                     // VTCM注入：bank选择在循环中处理
 
//=================================================================================
// ECC 错误注入实现（仅在TCM_ECC_EN使能时生效）
//=================================================================================
// 功能：在TCM读数据中注入单比特或多比特错误，用于测试ECC检测和纠正功能
// 原理：通过XOR操作翻转指定位置的位，模拟存储或传输过程中的位翻转错误

if (TCM_ECC_EN) begin : g_ecc_inject // 仅在 TCM ECC 总体支持开启时，才允许注入

//=================================================================================
// ITCM 错误注入：64位数据宽度
//=================================================================================
// ITCM读数据为64位，注入时只修改低64位，高位保持不变
// 注入方式：低32位使用bitmapl掩码，高32位使用bitmaph掩码
assign itcm_rdata_pre     = ecc_inject_itcm ? (itcm_ram_rdata[63:0] ^ {csr_inject_bitmaph, csr_inject_bitmapl}) : itcm_ram_rdata[63:0]; // 注入错误
assign itcm_rdata         = {itcm_ram_rdata[`CHUNJUN_ITCM_RAM_DATA_W-1:64], itcm_rdata_pre}; // 保持高位不变

//=================================================================================
// DTCM0 错误注入：双32位bank结构
//=================================================================================
// DTCM0分为lo和hi两个32位bank，分别注入错误
// lo bank使用bitmapl掩码，hi bank使用bitmaph掩码
assign dtcm0_rdata_lo_pre = ecc_inject_dtcm0 ? (dtcm0_ram_lo_rdata[31:0] ^ csr_inject_bitmapl) : dtcm0_ram_lo_rdata[31:0]; // 注入错误
assign dtcm0_rdata_hi_pre = ecc_inject_dtcm0 ? (dtcm0_ram_hi_rdata[31:0] ^ csr_inject_bitmaph) : dtcm0_ram_hi_rdata[31:0]; // 注入错误
assign dtcm0_rdata_lo     = {dtcm0_ram_lo_rdata[`CHUNJUN_DTCM_RAM_DATA_W-1:32], dtcm0_rdata_lo_pre}; // 保持高位不变
assign dtcm0_rdata_hi     = {dtcm0_ram_hi_rdata[`CHUNJUN_DTCM_RAM_DATA_W-1:32], dtcm0_rdata_hi_pre}; // 保持高位不变

//=================================================================================
// DTCM1 错误注入：双32位bank结构（可选）
//=================================================================================
`ifdef CHUNJUN_SUPPORT_DTCM1
// DTCM1的注入逻辑与DTCM0相同，但使用独立的注入使能信号
assign dtcm1_rdata_lo_pre = ecc_inject_dtcm1 ? (dtcm1_ram_lo_rdata[31:0] ^ csr_inject_bitmapl) : dtcm1_ram_lo_rdata[31:0]; // DTCM1 低 32b 注入
assign dtcm1_rdata_hi_pre = ecc_inject_dtcm1 ? (dtcm1_ram_hi_rdata[31:0] ^ csr_inject_bitmaph) : dtcm1_ram_hi_rdata[31:0]; // DTCM1 高 32b 注入
assign dtcm1_rdata_lo     = {dtcm1_ram_lo_rdata[`CHUNJUN_DTCM_RAM_DATA_W-1:32], dtcm1_rdata_lo_pre}; // 保持高位不变
assign dtcm1_rdata_hi     = {dtcm1_ram_hi_rdata[`CHUNJUN_DTCM_RAM_DATA_W-1:32], dtcm1_rdata_hi_pre}; // 保持高位不变
`endif // CHUNJUN_SUPPORT_DTCM1

//=================================================================================
// VTCM 错误注入：多bank向量结构（可选）
//=================================================================================
// VTCM包含多个32位bank，通过循环为每个bank注入错误
// bank选择：csr_inject_bank[i/2]选择bank组
// 掩码选择：i%2决定使用bitmapl还是bitmaph
`ifdef CHUNJUN_SUPPORT_V_EXT
for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_ecc_inject

  assign vtcm_rdata_pre[i] = (ecc_inject_vtcm & csr_inject_bank[i/2]) ? // 注入使能 & bank选择  
                             ((i%2 == 1)                              ? (vtcm_ram_rdata[i][31:0] ^ csr_inject_bitmaph) : (vtcm_ram_rdata[i][31:0] ^ csr_inject_bitmapl)) // 选择掩码
                                                                      : vtcm_ram_rdata[i][31:0]; // 保持高位不变
  assign vtcm_rdata[i]     = {vtcm_ram_rdata[i][`CHUNJUN_VTCM_RAM_DATA_W-1:32], vtcm_rdata_pre[i]}; // 保持高位不变

end
`endif // CHUNJUN_SUPPORT_V_EXT
 
//=================================================================================
// ECC 功能禁用时的直通模式
//=================================================================================
// 当TCM_ECC_EN为0时，所有TCM读数据直接通过，不进行任何错误注入
// 这确保了在ECC功能关闭时系统的正常运行

end else begin: g_no_ecc_inject

// ITCM数据直通：无ECC注入
assign itcm_rdata     = itcm_ram_rdata;

// DTCM0数据直通：lo和hi bank分别直通
assign dtcm0_rdata_lo = dtcm0_ram_lo_rdata;
assign dtcm0_rdata_hi = dtcm0_ram_hi_rdata;

// DTCM1数据直通（可选）：lo和hi bank分别直通
`ifdef CHUNJUN_SUPPORT_DTCM1
assign dtcm1_rdata_lo = dtcm1_ram_lo_rdata;
assign dtcm1_rdata_hi = dtcm1_ram_hi_rdata;
`endif // CHUNJUN_SUPPORT_DTCM1

// VTCM数据直通（可选）：所有bank直通
`ifdef CHUNJUN_SUPPORT_V_EXT
assign vtcm_rdata     = vtcm_ram_rdata;
`endif // CHUNJUN_SUPPORT_V_EXT
 
end

//=================================================================================
// ITCM Arbiter
//=================================================================================

// slv-bus/sbu uses ibank_busy pre-arbitration to increase efficiency.
assign iarb_req[MUX_ITCM_ICU]       = icu_iarb_req_vld;                 //ICU请求直接进入仲裁，不受bank_busy影响
assign iarb_req[MUX_ITCM_SLV]       = slv_iarb_req_vld & ~ibank_busy;   //SLV请求需要等待bank空闲
assign iarb_req[MUX_ITCM_LSU0]      = lsu_ld0_iarb_req_vld;             //LSU Load0请求直接进入仲裁，不受bank_busy影响
assign iarb_req[MUX_ITCM_LSU1]      = lsu_ld1_iarb_req_vld;             //LSU Load1请求直接进入仲裁，不受bank_busy影响
assign iarb_req[MUX_ITCM_SBU]       = sbu_iarb_req_vld & ~ibank_busy;    //SBU请求需要等待bank空闲
assign iarb_req[MUX_ITCM_VPU0]      = vpu_ld0_iarb_req_vld;             //VPU Load0请求直接进入仲裁，不受bank_busy影响
assign iarb_req[MUX_ITCM_VPU1]      = vpu_ld1_iarb_req_vld;             //VPU Load1请求直接进入仲裁，不受bank_busy影响
 
assign iarb_req_addr[MUX_ITCM_ICU]  = icu_tcu_req_addr_m1;              //ICU的20位地址直接传递
assign iarb_req_addr[MUX_ITCM_SLV]  = bmu_req_addr_mux;                 //{bmu_tcu_req_addr[20-1:3], 3'b000};
assign iarb_req_addr[MUX_ITCM_LSU0] = lsu_tcu_ld_req_addr_m1[0];        //LSU Load0的20位地址直接传递
assign iarb_req_addr[MUX_ITCM_LSU1] = lsu_tcu_ld_req_addr_m1[1];        //LSU Load1的20位地址直接传递
assign iarb_req_addr[MUX_ITCM_SBU]  = sbu_tcu_req_addr;                 //SBU的20位地址直接传递
`ifdef CHUNJUN_SUPPORT_V_EXT
assign iarb_req_addr[MUX_ITCM_VPU0] = vpu_tcu_ld_req_addr_m1[0];          //VPU Load0的20位地址直接传递
assign iarb_req_addr[MUX_ITCM_VPU1] = vpu_tcu_ld_req_addr_m1[1];          //VPU Load1的20位地址直接传递
`else //CHUNJUN_SUPOORT_V_EXT
assign iarb_req_addr[MUX_ITCM_VPU0] = {20{1'b0}};                       //VPU Load0的20位地址直接传递
assign iarb_req_addr[MUX_ITCM_VPU1] = {20{1'b0}};                       //VPU Load1的20位地址直接传递
`endif //CHUNJUN_SUPPORT_V_EXT
 
assign iarb_req_id[MUX_ITCM_ICU]    = aln_req_id_icu;    //使用对齐后的ICU请求ID
assign iarb_req_id[MUX_ITCM_SLV]    = aln_req_id_slv;    //使用对齐后的SLV请求ID
assign iarb_req_id[MUX_ITCM_LSU0]   = aln_req_id_lsu[0];  //使用对齐后的LSU Load0请求ID
assign iarb_req_id[MUX_ITCM_LSU1]   = aln_req_id_lsu[1];  //使用对齐后的LSU Load1请求ID
assign iarb_req_id[MUX_ITCM_SBU]    = aln_req_id_sbu;     //使用对齐后的SBU请求ID
assign iarb_req_id[MUX_ITCM_VPU0]   = aln_req_id_vpu[0];  //使用对齐后的VPU Load0请求ID
assign iarb_req_id[MUX_ITCM_VPU1]   = aln_req_id_vpu[1];  //使用对齐后的VPU Load1请求ID
 
// Only request that possibly write are included, for wr/wdata/wstrb.
// - [0]: Slave-bus read or write.
// - [1]: SBU write only.

// bit0 表示SLV请求的写使能，bit1 表示SBU请求的写使能
assign iarb_req_wr   [0] = bmu_req_wr_mux;  //SLV请求的写使能
assign iarb_req_wr   [1] = 1'b1;            //SBU请求的写使能

// bit0 表示SLV请求的写掩码，bit1 表示SBU请求的写掩码
assign iarb_req_wstrb[0] = bmu_req_wstrb_mux;  //SLV请求的写掩码, byte使能
assign iarb_req_wstrb[1] = sbu_tcu_req_wstrb;  //SBU请求的写掩码, byte使能
 
`ifdef CHUNJUN_SUPPORT_MEM_ECC
assign iarb_req_wdata[0] = bmu_wdata_post_enc_64;  //SLV请求的ecc后的写数据
assign iarb_req_wdata[1] = sbu_wdata_post_enc_64;  //SBU请求的ecc后的写数据
`else // CHUNJUN_SUPPORT_MEM_ECC
assign iarb_req_wdata[0] = bmu_req_wdata_mux;  //SLV请求的写数据
assign iarb_req_wdata[1] = sbu_tcu_req_wdata;  //SBU请求的写数据
`endif // CHUNJUN_SUPPORT_MEM_ECC

// Fixed priority from LSB to MSB.
// MODE=0：从LSB（最低位）到MSB（最高位）查找第一个1, MODE=1：从MSB（最高位）到LSB（最低位）查找第一个1
// LOCK=0：无锁定功能，每个周期重新仲裁, LOCK=1：支持锁定功能，锁定期间保持仲裁结果
// 输入宽度为7位，对应7个请求源
// input {VPU1, VPU0, SBU, LSU1, LSU0, SLV, ICU}
// output {VPU1, VPU0, SBU, LSU1, LSU0, SLV, ICU}, 7位one-hot输出向量, 只有一位为1，表示被选中的请求源
// 模式配置，0表示固定优先级模式,  输入宽度为7位，对应7个请求源,   LOCK(0)：锁定功能禁用
// iarb_req = 7'b0010101, 表示 ICU、LSU0、VPU0 请求有效
// iarb_grt = 7'b0000001, 表示 ICU 请求被选中
wing_cbb_priority_queue #(.MODE(0), .WIDTH(7), .LOCK(0)) u_ff1_iarb (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(iarb_req), .onehot_o(iarb_grt));

assign ibank_req_vld_m1 = |iarb_req;  //仲裁请求有效

//只要存在有效请求，就选出地址和ID
wing_cbb_aomux #(.NUM(7), .WIDTH(20      )) u_aomux_iarb_addr (.data_arr(iarb_req_addr), .sel_in_onehot0(iarb_grt), .data_sel(ibank_req_addr_m1));
wing_cbb_aomux #(.NUM(7), .WIDTH(TCM_ID_W)) u_aomux_iarb_id   (.data_arr(iarb_req_id  ), .sel_in_onehot0(iarb_grt), .data_sel(ibank_req_id_m1  ));

// only SBU and SLV will write TCM bank
assign iarb_grt_wo = {iarb_grt[MUX_ITCM_SBU], iarb_grt[MUX_ITCM_SLV]};

//当SBU和SLV请求有效时，选出wr、wdata、wstrb
wing_cbb_aomux #(.NUM(2), .WIDTH(1                       )) u_aomux_iarb_wr    (.data_arr(iarb_req_wr   ), .sel_in_onehot0(iarb_grt_wo), .data_sel(ibank_req_wr_m1   )); //当SBU和SLV请求有效时，选出wr
wing_cbb_aomux #(.NUM(2), .WIDTH(`CHUNJUN_ITCM_RAM_DATA_W)) u_aomux_iarb_wdata (.data_arr(iarb_req_wdata), .sel_in_onehot0(iarb_grt_wo), .data_sel(ibank_req_wdata_m1)); //当SBU和SLV请求有效时，选出wdata
wing_cbb_aomux #(.NUM(2), .WIDTH(8                       )) u_aomux_iarb_wstrb (.data_arr(iarb_req_wstrb), .sel_in_onehot0(iarb_grt_wo), .data_sel(ibank_req_wstrb_m1)); //当SBU和SLV请求有效时，选出wstrb

assign iarb_icu_req_rdy  = iarb_grt[MUX_ITCM_ICU] & ibank_req_rdy_m1; //ICU请求被选中且bank_req_rdy_m1为1时，请求被接受
assign iarb_slv_req_rdy  = iarb_grt[MUX_ITCM_SLV]; //SLV请求被选中时，请求被接受，之前通过ibank_busy信号过滤了无效请求
assign iarb_lsu0_req_rdy = iarb_grt[MUX_ITCM_LSU0] & ibank_req_rdy_m1; //LSU0请求被选中且bank_req_rdy_m1为1时，请求被接受
assign iarb_lsu1_req_rdy = iarb_grt[MUX_ITCM_LSU1] & ibank_req_rdy_m1; //LSU1请求被选中且bank_req_rdy_m1为1时，请求被接受
assign iarb_sbu_req_rdy  = iarb_grt[MUX_ITCM_SBU]; //SBU请求被选中时，请求被接受，之前通过ibank_busy信号过滤了无效请求
assign iarb_vpu0_req_rdy = iarb_grt[MUX_ITCM_VPU0] & ibank_req_rdy_m1; //VPU0请求被选中且bank_req_rdy_m1为1时，请求被接受
assign iarb_vpu1_req_rdy = iarb_grt[MUX_ITCM_VPU1] & ibank_req_rdy_m1; //VPU1请求被选中且bank_req_rdy_m1为1时，请求被接受

//=================================================================================
// ITCM Bank Instantiation
//=================================================================================
// - bank_busy is set when: 
//   - partial write in progress
//   - atop in progress
//   - ECC SEC value self-write
// 
// - req_rdy get NO arbitration when:
//   - write stage of partial write 
//   - write stage of atop
//   - ECC SEC value self-write
//
// - ICU and LSU rd requests use req_rdy to control handshake.
// - SBU and Slave-bus requests use bank_busy to mask valid.

//=================================================================================
// ITCM Bank实例化 - 指令TCM存储单元
//=================================================================================

chunjun_tcu_bank #(
    .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
    .LSQID_W    ( ($clog2(6) + 1)          ),  // LSU队列ID位宽
    .DATA_W     ( 64                        ),  // 数据位宽（64位）
    .RAM_DATA_W ( `CHUNJUN_ITCM_RAM_DATA_W  ),  // RAM数据位宽
    .RAM_ADDR_W ( `CHUNJUN_ITCM_RAM_ADDR_W  ),  // RAM地址位宽
    .SLV_SPLIT_N( 2                         ),  // Slave拆分数量
    .ECC_EN     ( TCM_ECC_EN                ),  // ECC使能
    .ATOP_EN    ( 0                         ),  // 原子操作使能（ITCM不支持）
    .WAIT_EN    ( ITCM_WAIT_EN              ),  // 等待使能
    .VBANK_N    ( 0                         )   // 向量Bank数量（ITCM无向量Bank）
) u_itcm_bank (
    //=================================================================================
    // 时钟和复位信号
    //=================================================================================
    .clk                   ( clk                      ),  // 时钟信号
    .rst_n                 ( rst_n                    ),  // 低电平有效复位信号
    
    //=================================================================================
    // 控制信号
    //=================================================================================
    .csr_ecc_en            ( csr_ecc_en               ),  // CSR ECC使能信号
    
    //=================================================================================
    // Flush和Cancel信号
    //=================================================================================
    .icu_flush             ( icu_tcu_flush_m2         ),  // ICU flush信号（M2阶段）
    .icu_cancel            ( icu_tcu_cancel_m2        ),  // ICU cancel信号（M2阶段）
    .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2 ),  // LSU cancel信号（M2阶段）
    .lsu_flush             ( lsu_tcu_flush_valid      ),  // LSU flush有效信号
    .lsu_flush_id          ( lsu_tcu_flush_lsqid      ),  // LSU flush ID
    .vpu_cancel            ( vpu_tcu_cancel_m2        ),  // VPU cancel信号（M2阶段）
    
    //=================================================================================
    // M1阶段请求信号（输入）
    //=================================================================================
    .bank_req_vld_m1       ( ibank_req_vld_m1         ),  // Bank请求有效信号
    .bank_req_rdy_m1       ( ibank_req_rdy_m1         ),  // Bank请求就绪信号（输出）
    .bank_req_addr_m1      ( ibank_req_addr_m1        ),  // Bank请求地址
    .bank_req_id_m1        ( ibank_req_id_m1          ),  // Bank请求ID
    .bank_req_wr_m1        ( ibank_req_wr_m1          ),  // Bank请求写使能（0=读，1=写）
    .bank_req_wdata_m1     ( ibank_req_wdata_m1       ),  // Bank请求写数据
    .bank_req_wstrb_m1     ( ibank_req_wstrb_m1       ),  // Bank请求写选通信号
    .bank_req_atop_m1      ( 6'b0                     ),  // Bank请求原子操作码（ITCM不支持，固定为0）
    .bank_req_data_dest_m1 ( 2'b0                     ),  // Bank请求数据目标（ITCM不支持，固定为0）
    
    //=================================================================================
    // 状态指示信号（输出）
    //=================================================================================
    .into_partial_m1       ( ibank_into_partial_m1    ),  // 进入部分写状态
    .into_atomic_m1        (                          ),  // 进入原子操作状态（ITCM不支持，未连接）
    .bank_busy             ( ibank_busy               ),  // Bank忙状态
    .bank_idle             ( ibank_idle               ),  // Bank空闲状态
    
    //=================================================================================
    // RAM接口信号（输出到RAM）
    //=================================================================================
    .ram_cs_m1             ( itcm_ram_cs              ),  // RAM片选信号
    .ram_wr_m1             ( itcm_ram_wr              ),  // RAM写使能信号
    .ram_addr_m1           ( itcm_ram_addr            ),  // RAM地址信号
    .ram_wen_m1            ( itcm_ram_wen             ),  // RAM写选通信号
    .ram_wdata_m1          ( itcm_ram_wdata           ),  // RAM写数据
    .ram_rdata_m2          ( itcm_rdata               ),  // RAM读数据（M2阶段输入）
    
    //=================================================================================
    // Hold寄存器信号 （输出）（用于部分写和原子操作）
    //=================================================================================
    .hold_wdata            ( ibank_hold_wdata         ),  // Hold写数据
    .hold_wstrb            ( ibank_hold_wstrb         ),  // Hold写选通
    .hold_atop             ( 6'b0                     ),  // Hold原子操作码（ITCM不支持，固定为0）
    .hold_cmp_val          ( 64'b0                    ),  // Hold比较值（ITCM不支持，固定为0）
    
    //=================================================================================
    // M2阶段响应信号（输出）
    //=================================================================================
    .bank_rsp_vld_m2       ( ibank_rsp_vld_m2         ),  // Bank响应有效信号
    .bank_rsp_id_m2        ( ibank_rsp_id_m2          ),  // Bank响应ID
    .bank_rsp_data_m2      ( ibank_rsp_data_m2        ),  // Bank响应数据
    .bank_rsp_se_m2        ( ibank_rsp_se_m2          ),  // Bank响应单bit错误信号
    .bank_rsp_de_m2        ( ibank_rsp_de_m2          ),  // Bank响应双bit错误信号
    .bank_rsp_data_dest_m2 (                          ),  // Bank响应数据目标（ITCM不支持，未连接）
    .bank_rsp_addr_m2      ( ibank_rsp_addr_m2        ),  // Bank响应地址
    
    //=================================================================================
    // M3阶段响应信号（输出）
    //=================================================================================
    .bank_rsp_vld_m3       ( ibank_rsp_vld_m3         ),  // Bank响应有效信号
    .bank_rsp_id_m3        ( ibank_rsp_id_m3          ),  // Bank响应ID
    .bank_rsp_data_m3      ( ibank_rsp_data_m3        ),  // Bank响应数据
    .bank_rsp_se_m3        ( ibank_rsp_se_m3          ),  // Bank响应单bit错误信号
    .bank_rsp_de_m3        ( ibank_rsp_de_m3          ),  // Bank响应双bit错误信号
    .bank_rsp_data_dest_m3 (                          ),  // Bank响应数据目标（ITCM不支持，未连接）
    .bank_rsp_addr_m3      ( ibank_rsp_addr_m3        ),  // Bank响应地址
    
    //=================================================================================
    // 原子操作状态信号（输出）
    //=================================================================================
    .bank_atop_b_infly_m3  (                          ),  // Bank原子操作B响应进行中（ITCM不支持，未连接）
    .bank_atop_r_infly_m3  (                          ),  // Bank原子操作R响应进行中（ITCM不支持，未连接）
    
    //=================================================================================
    // RAS错误报告信号（输出）
    //=================================================================================
    .bank_rsp_vld_ras      ( ibank_rsp_vld_ras        ),  // RAS响应有效信号
    .bank_rsp_id_ras       ( ibank_rsp_id_ras         ),  // RAS响应ID
    .bank_rsp_se_ras       ( ibank_rsp_se_ras         ),  // RAS响应单bit错误信号
    .bank_rsp_de_ras       ( ibank_rsp_de_ras         ),  // RAS响应双bit错误信号
    .bank_rsp_wr_ras       ( ibank_rsp_wr_ras         ),  // RAS响应写操作信号
    .bank_rsp_addr_ras     ( ibank_rsp_addr_ras       )   // RAS响应地址
);

//=================================================================================
// ITCM Bank Partial-Wr Register
//=================================================================================
// store wdata and wstrb for partial write
if (TCM_ECC_EN) begin: g_itcm_hold_reg

  `WDFFER(ibank_hold_wdata, ibank_req_wdata_m1[63:0], ibank_into_partial_m1, clk, rst_n) //当ECC使能时，ITCM进入部分写状态时，保持写数据
  `WDFFER(ibank_hold_wstrb, ibank_req_wstrb_m1,       ibank_into_partial_m1, clk, rst_n) //当ECC使能时，ITCM进入部分写状态时，保持写选通
 
end else begin: g_itcm_nohold

  assign ibank_hold_wdata = 64'b0; //当ECC关闭时，ITCM保持写数据为0
  assign ibank_hold_wstrb = 8'b0; //当ECC关闭时，ITCM保持写选通为0
 
end

//=================================================================================
// DTCM0 Arbiter - 数据紧耦合存储器0仲裁器
// 功能：仲裁来自多个主设备(ICU、LSU、SBU、SLV、VPU)的DTCM0访问请求
// 将请求路由到两个bank(lo和hi)以实现并行访问
//=================================================================================
chunjun_tcu_dtcmarb #(
    .ID_W       ( TCM_ID_W                 ),  // 请求ID位宽
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W ),  // RAM数据位宽
    .ATOP_EN    ( DTCM_ATOP_EN             )   // 原子操作使能
) u_tcu_dtcm0_arb (
    // 时钟和复位信号
    .clk                ( clk                     ),  // 系统时钟
    .rst_n              ( rst_n                   ),  // 低电平有效复位
    
    // ICU(指令缓存单元)接口 - 只读访问
    .icu_dtcm_req_vld   ( icu_dtcm0_req_vld       ),  // ICU请求有效
    .dtcm_icu_req_rdy   ( dtcm0_icu_req_rdy       ),  // DTCM0对ICU请求就绪
    .icu_dtcm_req_addr  ( icu_tcu_req_addr_m1     ),  // ICU请求地址
    .icu_dtcm_req_id    ( aln_req_id_icu          ),  // ICU请求ID
    
    // LSU(加载存储单元)接口 - 读写访问
    .lsu_dtcm_req_vld   ( lsu_dtcm0_req_vld       ),  // LSU请求有效
    .dtcm_lsu_req_rdy   ( dtcm0_lsu_req_rdy       ),  // DTCM0对LSU请求就绪
    .lsu_dtcm_req_addr  ( lsu_tcu_ld_req_addr_m1  ),  // LSU请求地址
    .lsu_dtcm_req_id    ( aln_req_id_lsu          ),  // LSU请求ID
    
    // SBU(系统总线单元)接口 - 支持原子操作
    .sbu_dtcm_req_vld   ( sbu_dtcm0_req_vld       ),  // SBU请求有效
    .dtcm_sbu_req_rdy   ( dtcm0_sbu_req_rdy       ),  // DTCM0对SBU请求就绪
    .sbu_dtcm_req_addr  ( sbu_tcu_req_addr        ),  // SBU请求地址
    .sbu_dtcm_req_id    ( aln_req_id_sbu          ),  // SBU请求ID
    .sbu_dtcm_req_wdata ( sbu_dtcm_wdata          ),  // SBU写数据
    .sbu_dtcm_req_wstrb ( sbu_tcu_req_wstrb       ),  // SBU写字节使能
    .sbu_dtcm_req_atop  ( sbu_tcu_req_atop        ),  // SBU原子操作类型
    
    // SLV(从设备)接口 - 通过BMU访问
    .slv_dtcm_req_vld   ( slv_dtcm0_req_vld       ),  // SLV请求有效
    .dtcm_slv_req_rdy   ( dtcm0_slv_req_rdy       ),  // DTCM0对SLV请求就绪
    .slv_dtcm_req_addr  ( bmu_req_addr_mux        ),  // SLV请求地址(多路复用)
    .slv_dtcm_req_id    ( aln_req_id_slv          ),  // SLV请求ID
    .slv_dtcm_req_wr    ( bmu_req_wr_mux          ),  // SLV写使能(多路复用)
    .slv_dtcm_req_wdata ( bmu_dtcm_wdata          ),  // SLV写数据
    .slv_dtcm_req_wstrb ( bmu_req_wstrb_mux       ),  // SLV写字节使能(多路复用)
    
    // VPU(向量处理单元)接口
    .vpu_dtcm_req_vld   ( vpu_dtcm0_req_vld       ),  // VPU请求有效
    .dtcm_vpu_req_rdy   ( dtcm0_vpu_req_rdy       ),  // DTCM0对VPU请求就绪
    .vpu_dtcm_req_addr  ( vpu_dtcm0_req_addr      ),  // VPU请求地址
    .vpu_dtcm_req_id    ( aln_req_id_vpu          ),  // VPU请求ID
    
    // 低bank接口 - 处理地址的低位部分
    .bank_lo_vld        ( dbank0_lo_req_vld_m1    ),  // 低bank请求有效
    .bank_lo_rdy        ( dbank0_lo_req_rdy_m1    ),  // 低bank就绪
    .bank_lo_addr       ( dbank0_lo_req_addr_m1   ),  // 低bank请求地址
    .bank_lo_id         ( dbank0_lo_req_id_m1     ),  // 低bank请求ID
    .bank_lo_wr         ( dbank0_lo_req_wr_m1     ),  // 低bank写使能
    .bank_lo_wdata      ( dbank0_lo_req_wdata_m1  ),  // 低bank写数据
    .bank_lo_wstrb      ( dbank0_lo_req_wstrb_m1  ),  // 低bank写字节使能
    .bank_lo_atop       ( dbank0_lo_req_atop_m1   ),  // 低bank原子操作类型
    
    // 高bank接口 - 处理地址的高位部分
    .bank_hi_vld        ( dbank0_hi_req_vld_m1    ),  // 高bank请求有效
    .bank_hi_rdy        ( dbank0_hi_req_rdy_m1    ),  // 高bank就绪
    .bank_hi_addr       ( dbank0_hi_req_addr_m1   ),  // 高bank请求地址
    .bank_hi_id         ( dbank0_hi_req_id_m1     ),  // 高bank请求ID
    .bank_hi_wr         ( dbank0_hi_req_wr_m1     ),  // 高bank写使能
    .bank_hi_wdata      ( dbank0_hi_req_wdata_m1  ),  // 高bank写数据
    .bank_hi_wstrb      ( dbank0_hi_req_wstrb_m1  ),  // 高bank写字节使能
    .bank_hi_atop       ( dbank0_hi_req_atop_m1   ),  // 高bank原子操作类型
    
    // Bank状态反馈
    .bank_lo_busy       ( dbank0_lo_busy          ),  // 低bank忙状态
    .bank_hi_busy       ( dbank0_hi_busy          )   // 高bank忙状态
);

//=================================================================================
// DTCM0 Bank Instantiation - DTCM0存储器bank实例化
// 实现两个bank(lo和hi)以支持并行访问，提高存储器带宽
//=================================================================================

// DTCM0低bank实例 - 处理地址的低位部分
chunjun_tcu_bank #(
    .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
    .LSQID_W    ( ($clog2(6) + 1)          ),  // 加载存储队列ID位宽(6个LSU + 1)
    .DATA_W     ( 32                        ),  // 数据位宽32位
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W  ),  // RAM数据位宽
    .RAM_ADDR_W ( `CHUNJUN_DTCM0_RAM_ADDR_W ),  // RAM地址位宽
    .SLV_SPLIT_N( 2                         ),  // 从设备分割数量
    .ECC_EN     ( TCM_ECC_EN                ),  // ECC错误校正使能
    .ATOP_EN    ( DTCM_ATOP_EN              ),  // 原子操作使能
    .WAIT_EN    ( DTCM0_WAIT_EN             ),  // 等待使能
    .VBANK_N    ( 0                         )   // 虚拟bank编号(0表示物理bank)
) u_dtcm0_bank_lo (
    // 时钟、复位和控制信号
    .clk                   ( clk                      ),  // 系统时钟
    .rst_n                 ( rst_n                    ),  // 低电平有效复位
    .csr_ecc_en            ( csr_ecc_en               ),  // CSR ECC使能控制
    
    // 各主设备的刷新和取消信号
    .icu_flush             ( icu_tcu_flush_m2         ),  // ICU刷新信号(延迟2周期)
    .icu_cancel            ( icu_tcu_cancel_m2        ),  // ICU取消信号(延迟2周期)
    .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2 ),  // LSU取消信号(延迟2周期)
    .lsu_flush             ( lsu_tcu_flush_valid      ),  // LSU刷新有效
    .lsu_flush_id          ( lsu_tcu_flush_lsqid      ),  // LSU刷新队列ID
    .vpu_cancel            ( vpu_tcu_cancel_m2        ),  // VPU取消信号(延迟2周期)
    
    // Bank请求接口(延迟1周期)
    .bank_req_vld_m1       ( dbank0_lo_req_vld_m1     ),  // 请求有效
    .bank_req_rdy_m1       ( dbank0_lo_req_rdy_m1     ),  // 请求就绪
    .bank_req_addr_m1      ( dbank0_lo_req_addr_m1    ),  // 请求地址
    .bank_req_id_m1        ( dbank0_lo_req_id_m1      ),  // 请求ID
    .bank_req_wr_m1        ( dbank0_lo_req_wr_m1      ),  // 写使能
    .bank_req_wdata_m1     ( dbank0_lo_req_wdata_m1   ),  // 写数据
    .bank_req_wstrb_m1     ( dbank0_lo_req_wstrb_m1   ),  // 写字节使能
    .bank_req_atop_m1      ( dbank0_lo_req_atop_m1    ),  // 原子操作类型
    .bank_req_data_dest_m1 ( 2'b0                     ),  // 数据目标(固定为0)
    
    // 状态指示信号
    .into_partial_m1       ( dbank0_lo_into_partial_m1),  // 进入部分访问状态
    .into_atomic_m1        ( dbank0_lo_into_atomic_m1 ),  // 进入原子操作状态
    .bank_busy             ( dbank0_lo_busy           ),  // bank忙状态
    .bank_idle             ( dbank0_lo_idle           ),  // bank空闲状态
    
    // RAM接口(延迟1周期)
    .ram_cs_m1             ( dtcm0_ram_lo_cs          ),  // RAM片选
    .ram_wr_m1             ( dtcm0_ram_lo_wr          ),  // RAM写使能
    .ram_addr_m1           ( dtcm0_ram_lo_addr        ),  // RAM地址
    .ram_wen_m1            ( dtcm0_ram_lo_wen         ),  // RAM写使能(细粒度)
    .ram_wdata_m1          ( dtcm0_ram_lo_wdata       ),  // RAM写数据
    .ram_rdata_m2          ( dtcm0_rdata_lo           ),  // RAM读数据(延迟2周期)
    
    // 数据保持信号(用于原子操作)
    .hold_wdata            ( dbank0_hold_wdata_lo     ),  // 保持写数据
    .hold_wstrb            ( dbank0_hold_wstrb_lo     ),  // 保持写字节使能
    .hold_atop             ( dbank0_hold_atop_lo      ),  // 保持原子操作类型
    .hold_cmp_val          ( dbank0_hold_cmp_val      ),  // 保持比较值
    
    // Bank响应接口(延迟2周期)
    .bank_rsp_vld_m2       ( dbank0_lo_rsp_vld_m2     ),  // 响应有效
    .bank_rsp_id_m2        ( dbank0_lo_rsp_id_m2      ),  // 响应ID
    .bank_rsp_data_m2      ( dbank0_lo_rsp_data_m2    ),  // 响应数据
    .bank_rsp_se_m2        ( dbank0_lo_rsp_se_m2      ),  // 响应单比特错误
    .bank_rsp_de_m2        ( dbank0_lo_rsp_de_m2      ),  // 响应双比特错误
    .bank_rsp_data_dest_m2 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m2      ( dbank0_lo_rsp_addr_m2    ),  // 响应地址
    
    // Bank响应接口(延迟3周期)
    .bank_rsp_vld_m3       ( dbank0_lo_rsp_vld_m3     ),  // 响应有效
    .bank_rsp_id_m3        ( dbank0_lo_rsp_id_m3      ),  // 响应ID
    .bank_rsp_data_m3      ( dbank0_lo_rsp_data_m3    ),  // 响应数据
    .bank_rsp_se_m3        ( dbank0_lo_rsp_se_m3      ),  // 响应单比特错误
    .bank_rsp_de_m3        ( dbank0_lo_rsp_de_m3      ),  // 响应双比特错误
    .bank_rsp_data_dest_m3 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m3      ( dbank0_lo_rsp_addr_m3    ),  // 响应地址
    
    // 原子操作状态(延迟3周期)
    .bank_atop_b_infly_m3  ( dbank0_lo_atop_b_infly_m3),  // 原子操作B进行中
    .bank_atop_r_infly_m3  ( dbank0_lo_atop_r_infly_m3),  // 原子操作R进行中
    
    // RAS(Return Address Stack)响应接口
    .bank_rsp_vld_ras      ( dbank0_lo_rsp_vld_ras    ),  // RAS响应有效
    .bank_rsp_id_ras       ( dbank0_lo_rsp_id_ras     ),  // RAS响应ID
    .bank_rsp_se_ras       ( dbank0_lo_rsp_se_ras     ),  // RAS响应单比特错误
    .bank_rsp_de_ras       ( dbank0_lo_rsp_de_ras     ),  // RAS响应双比特错误
    .bank_rsp_wr_ras       ( dbank0_lo_rsp_wr_ras     ),  // RAS响应写标志
    .bank_rsp_addr_ras     ( dbank0_lo_rsp_addr_ras   )   // RAS响应地址
);

// DTCM0高bank实例 - 处理地址的高位部分
chunjun_tcu_bank #(
    .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
    .LSQID_W    ( ($clog2(6) + 1)          ),  // 加载存储队列ID位宽(6个LSU + 1)
    .DATA_W     ( 32                        ),  // 数据位宽32位
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W  ),  // RAM数据位宽
    .RAM_ADDR_W ( `CHUNJUN_DTCM0_RAM_ADDR_W ),  // RAM地址位宽
    .SLV_SPLIT_N( 2                         ),  // 从设备分割数量
    .ECC_EN     ( TCM_ECC_EN                ),  // ECC错误校正使能
    .ATOP_EN    ( DTCM_ATOP_EN              ),  // 原子操作使能
    .WAIT_EN    ( DTCM0_WAIT_EN             ),  // 等待使能
    .VBANK_N    ( 0                         )   // 虚拟bank编号(0表示物理bank)
) u_dtcm0_bank_hi (
    // 时钟、复位和控制信号
    .clk                   ( clk                      ),  // 系统时钟
    .rst_n                 ( rst_n                    ),  // 低电平有效复位
    .csr_ecc_en            ( csr_ecc_en               ),  // CSR ECC使能控制
    
    // 各主设备的刷新和取消信号
    .icu_flush             ( icu_tcu_flush_m2         ),  // ICU刷新信号(延迟2周期)
    .icu_cancel            ( icu_tcu_cancel_m2        ),  // ICU取消信号(延迟2周期)
    .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2 ),  // LSU取消信号(延迟2周期)
    .lsu_flush             ( lsu_tcu_flush_valid      ),  // LSU刷新有效
    .lsu_flush_id          ( lsu_tcu_flush_lsqid      ),  // LSU刷新队列ID
    .vpu_cancel            ( vpu_tcu_cancel_m2        ),  // VPU取消信号(延迟2周期)
    
    // Bank请求接口(延迟1周期)
    .bank_req_vld_m1       ( dbank0_hi_req_vld_m1     ),  // 请求有效
    .bank_req_rdy_m1       ( dbank0_hi_req_rdy_m1     ),  // 请求就绪
    .bank_req_addr_m1      ( dbank0_hi_req_addr_m1    ),  // 请求地址
    .bank_req_id_m1        ( dbank0_hi_req_id_m1      ),  // 请求ID
    .bank_req_wr_m1        ( dbank0_hi_req_wr_m1      ),  // 写使能
    .bank_req_wdata_m1     ( dbank0_hi_req_wdata_m1   ),  // 写数据
    .bank_req_wstrb_m1     ( dbank0_hi_req_wstrb_m1   ),  // 写字节使能
    .bank_req_data_dest_m1 ( 2'b0                     ),  // 数据目标(固定为0)
    .bank_req_atop_m1      ( dbank0_hi_req_atop_m1    ),  // 原子操作类型
    
    // 状态指示信号
    .into_partial_m1       ( dbank0_hi_into_partial_m1),  // 进入部分访问状态
    .into_atomic_m1        ( dbank0_hi_into_atomic_m1 ),  // 进入原子操作状态
    .bank_busy             ( dbank0_hi_busy           ),  // bank忙状态
    .bank_idle             ( dbank0_hi_idle           ),  // bank空闲状态
    
    // RAM接口(延迟1周期)
    .ram_cs_m1             ( dtcm0_ram_hi_cs          ),  // RAM片选
    .ram_wr_m1             ( dtcm0_ram_hi_wr          ),  // RAM写使能
    .ram_addr_m1           ( dtcm0_ram_hi_addr        ),  // RAM地址
    .ram_wen_m1            ( dtcm0_ram_hi_wen         ),  // RAM写使能(细粒度)
    .ram_wdata_m1          ( dtcm0_ram_hi_wdata       ),  // RAM写数据
    .ram_rdata_m2          ( dtcm0_rdata_hi           ),  // RAM读数据(延迟2周期)
    
    // 数据保持信号(用于原子操作)
    .hold_wdata            ( dbank0_hold_wdata_hi     ),  // 保持写数据
    .hold_wstrb            ( dbank0_hold_wstrb_hi     ),  // 保持写字节使能
    .hold_atop             ( dbank0_hold_atop_hi      ),  // 保持原子操作类型
    .hold_cmp_val          ( dbank0_hold_cmp_val      ),  // 保持比较值
    
    // Bank响应接口(延迟2周期)
    .bank_rsp_vld_m2       ( dbank0_hi_rsp_vld_m2     ),  // 响应有效
    .bank_rsp_id_m2        ( dbank0_hi_rsp_id_m2      ),  // 响应ID
    .bank_rsp_data_m2      ( dbank0_hi_rsp_data_m2    ),  // 响应数据
    .bank_rsp_se_m2        ( dbank0_hi_rsp_se_m2      ),  // 响应单比特错误
    .bank_rsp_de_m2        ( dbank0_hi_rsp_de_m2      ),  // 响应双比特错误
    .bank_rsp_data_dest_m2 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m2      ( dbank0_hi_rsp_addr_m2    ),  // 响应地址
    
    // Bank响应接口(延迟3周期)
    .bank_rsp_vld_m3       ( dbank0_hi_rsp_vld_m3     ),  // 响应有效
    .bank_rsp_id_m3        ( dbank0_hi_rsp_id_m3      ),  // 响应ID
    .bank_rsp_data_m3      ( dbank0_hi_rsp_data_m3    ),  // 响应数据
    .bank_rsp_se_m3        ( dbank0_hi_rsp_se_m3      ),  // 响应单比特错误
    .bank_rsp_de_m3        ( dbank0_hi_rsp_de_m3      ),  // 响应双比特错误
    .bank_rsp_data_dest_m3 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m3      ( dbank0_hi_rsp_addr_m3    ),  // 响应地址
    
    // 原子操作状态(延迟3周期)
    .bank_atop_b_infly_m3  ( dbank0_hi_atop_b_infly_m3),  // 原子操作B进行中
    .bank_atop_r_infly_m3  ( dbank0_hi_atop_r_infly_m3),  // 原子操作R进行中
    
    // RAS(Return Address Stack)响应接口
    .bank_rsp_vld_ras      ( dbank0_hi_rsp_vld_ras    ),  // RAS响应有效
    .bank_rsp_id_ras       ( dbank0_hi_rsp_id_ras     ),  // RAS响应ID
    .bank_rsp_se_ras       ( dbank0_hi_rsp_se_ras     ),  // RAS响应单比特错误
    .bank_rsp_de_ras       ( dbank0_hi_rsp_de_ras     ),  // RAS响应双比特错误
    .bank_rsp_wr_ras       ( dbank0_hi_rsp_wr_ras     ),  // RAS响应写标志
    .bank_rsp_addr_ras     ( dbank0_hi_rsp_addr_ras   )   // RAS响应地址
);

//=================================================================================
// DTCM0 Bank Hold Register - DTCM0 Bank保持寄存器
// 功能：在ECC部分写操作和原子操作期间保持写数据和写字节使能信号
// 原因：
// 1. ECC部分写操作：需要保持原始数据以进行ECC编码
// 2. 原子操作：需要保持比较和交换的数据
//=================================================================================
// 保持写数据逻辑：当启用ECC或原子操作时
if (TCM_ECC_EN || DTCM_ATOP_EN) begin: g_dtcm0_hold_wdata
 
  // 组合逻辑：检测是否进入部分写或原子操作状态
  assign dbank0_into_partial_m1 = dbank0_lo_into_partial_m1 | dbank0_hi_into_partial_m1;  // 任一bank进入部分写状态
  assign dbank0_into_atomic_m1  = dbank0_lo_into_atomic_m1  | dbank0_hi_into_atomic_m1;   // 任一bank进入原子操作状态

  // 写数据保持使能：当进入部分写或原子操作状态时
  assign dbank0_hold_wdata_en   = dbank0_into_partial_m1 | dbank0_into_atomic_m1;  // 写数据保持使能
  assign dbank0_hold_wdata_m1   = {dbank0_hi_req_wdata_m1[31:0], dbank0_lo_req_wdata_m1[31:0]};  // 组合64位写数据(hi[31:0], lo[31:0])

  // 写字节使能保持使能：当进入部分写或原子操作状态时
  assign dbank0_hold_wstrb_en   = dbank0_into_partial_m1 | dbank0_into_atomic_m1;  // 写字节使能保持使能
  assign dbank0_hold_wstrb_m1   = {dbank0_hi_req_wstrb_m1, dbank0_lo_req_wstrb_m1};  // 组合8位写字节使能(hi[3:0], lo[3:0])

  // 使用WDFFER宏实例化保持寄存器：在时钟上升沿采样数据
  `WDFFER(dbank0_hold_wdata, dbank0_hold_wdata_m1, dbank0_hold_wdata_en, clk, rst_n)  // 写数据保持寄存器
  `WDFFER(dbank0_hold_wstrb, dbank0_hold_wstrb_m1, dbank0_hold_wstrb_en, clk, rst_n)  // 写字节使能保持寄存器

  // 分离保持的写数据到各个bank
  assign dbank0_hold_wdata_lo = dbank0_hold_wdata[31: 0];  // 低bank保持的写数据
  assign dbank0_hold_wdata_hi = dbank0_hold_wdata[63:32];  // 高bank保持的写数据

  // 分离保持的写字节使能到各个bank
  assign dbank0_hold_wstrb_lo = dbank0_hold_wstrb[3:0];  // 低bank保持的写字节使能
  assign dbank0_hold_wstrb_hi = dbank0_hold_wstrb[7:4];  // 高bank保持的写字节使能

end else begin: g_dtcm0_no_hold_wdata
  // 当不启用ECC和原子操作时：保持信号置零
 
  assign dbank0_hold_wdata_lo = 32'b0;  // 低bank保持写数据置零
  assign dbank0_hold_wdata_hi = 32'b0;  // 高bank保持写数据置零

  assign dbank0_hold_wstrb_lo = 4'b0;  // 低bank保持写字节使能置零
  assign dbank0_hold_wstrb_hi = 4'b0;  // 高bank保持写字节使能置零
 
end

// 保持原子操作代码逻辑：当启用原子操作时
if (DTCM_ATOP_EN) begin: g_dtcm0_hold_atop

  // 原子操作类型保持信号：延迟1周期
  assign dbank0_lo_hold_atop_m1 = dbank0_lo_req_atop_m1;  // 低bank原子操作类型保持
  assign dbank0_hi_hold_atop_m1 = dbank0_hi_req_atop_m1;  // 高bank原子操作类型保持
  assign dbank0_atop_cmp_val_m1 = sbu_tcu_req_wdata[63:32];  // 原子操作比较值(来自SBU写数据的高32位)

  // 使用WDFFER宏实例化原子操作保持寄存器
  `WDFFER(dbank0_hold_atop_lo, dbank0_lo_hold_atop_m1, dbank0_lo_into_atomic_m1, clk, rst_n)  // 低bank原子操作类型保持寄存器
  `WDFFER(dbank0_hold_atop_hi, dbank0_hi_hold_atop_m1, dbank0_hi_into_atomic_m1, clk, rst_n)  // 高bank原子操作类型保持寄存器
  `WDFFER(dbank0_hold_cmp_val, dbank0_atop_cmp_val_m1, dbank0_into_atomic_m1   , clk, rst_n)  // 原子操作比较值保持寄存器
 
end else begin: g_dtcm0_no_hold_atop
  // 当不启用原子操作时：保持信号置零

  assign dbank0_hold_atop_lo = 6'b0;  // 低bank原子操作类型保持置零
  assign dbank0_hold_atop_hi = 6'b0;  // 高bank原子操作类型保持置零
  assign dbank0_hold_cmp_val = 32'b0;  // 原子操作比较值保持置零
 
end

//**********************************************************************************************//
`ifdef CHUNJUN_SUPPORT_DTCM1
//**********************************************************************************************//
//=================================================================================
// DTCM1 Arbiter - 数据紧耦合存储器1仲裁器
// 功能：仲裁来自多个主设备(ICU、LSU、SBU、SLV、VPU)的DTCM1访问请求
// 将请求路由到两个bank(lo和hi)以实现并行访问
//=================================================================================
chunjun_tcu_dtcmarb #(
    .ID_W       ( TCM_ID_W                 ),  // 请求ID位宽
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W ),  // RAM数据位宽
    .ATOP_EN    ( DTCM_ATOP_EN             )   // 原子操作使能
) u_tcu_dtcm1_arb (
    // 时钟和复位信号
    .clk                ( clk                     ),  // 系统时钟
    .rst_n              ( rst_n                   ),  // 低电平有效复位
    // ICU(指令缓存单元)接口 - 只读访问
    .icu_dtcm_req_vld   ( icu_dtcm1_req_vld       ),  // ICU请求有效
    .dtcm_icu_req_rdy   ( dtcm1_icu_req_rdy       ),  // DTCM1对ICU请求就绪
    .icu_dtcm_req_addr  ( icu_tcu_req_addr_m1     ),  // ICU请求地址(延迟1周期)
    .icu_dtcm_req_id    ( aln_req_id_icu          ),  // ICU请求ID
    // LSU(加载存储单元)接口 - 读写访问
    .lsu_dtcm_req_vld   ( lsu_dtcm1_req_vld       ),  // LSU请求有效
    .dtcm_lsu_req_rdy   ( dtcm1_lsu_req_rdy       ),  // DTCM1对LSU请求就绪
    .lsu_dtcm_req_addr  ( lsu_tcu_ld_req_addr_m1  ),  // LSU请求地址(延迟1周期)
    .lsu_dtcm_req_id    ( aln_req_id_lsu          ),  // LSU请求ID
    // SBU(系统总线单元)接口 - 读写访问，支持原子操作
    .sbu_dtcm_req_vld   ( sbu_dtcm1_req_vld       ),  // SBU请求有效
    .dtcm_sbu_req_rdy   ( dtcm1_sbu_req_rdy       ),  // DTCM1对SBU请求就绪
    .sbu_dtcm_req_addr  ( sbu_tcu_req_addr        ),  // SBU请求地址
    .sbu_dtcm_req_id    ( aln_req_id_sbu          ),  // SBU请求ID
    .sbu_dtcm_req_wdata ( sbu_dtcm_wdata          ),  // SBU写数据
    .sbu_dtcm_req_wstrb ( sbu_tcu_req_wstrb       ),  // SBU写字节使能
    .sbu_dtcm_req_atop  ( sbu_tcu_req_atop        ),  // SBU原子操作类型
    // SLV(从设备)接口 - 通过BMU访问，读写访问
    .slv_dtcm_req_vld   ( slv_dtcm1_req_vld       ),  // SLV请求有效
    .dtcm_slv_req_rdy   ( dtcm1_slv_req_rdy       ),  // DTCM1对SLV请求就绪
    .slv_dtcm_req_addr  ( bmu_req_addr_mux        ),  // SLV请求地址(多路复用)
    .slv_dtcm_req_id    ( aln_req_id_slv          ),  // SLV请求ID
    .slv_dtcm_req_wr    ( bmu_req_wr_mux          ),  // SLV写使能(多路复用)
    .slv_dtcm_req_wdata ( bmu_dtcm_wdata          ),  // SLV写数据
    .slv_dtcm_req_wstrb ( bmu_req_wstrb_mux       ),  // SLV写字节使能(多路复用)
    // VPU(向量处理单元)接口 - 读写访问
    .vpu_dtcm_req_vld   ( vpu_dtcm1_req_vld       ),  // VPU请求有效
    .dtcm_vpu_req_rdy   ( dtcm1_vpu_req_rdy       ),  // DTCM1对VPU请求就绪
    .vpu_dtcm_req_addr  ( vpu_dtcm1_req_addr      ),  // VPU请求地址
    .vpu_dtcm_req_id    ( aln_req_id_vpu          ),  // VPU请求ID
    // 低bank接口(延迟1周期)
    .bank_lo_vld        ( dbank1_lo_req_vld_m1    ),  // 低bank请求有效
    .bank_lo_rdy        ( dbank1_lo_req_rdy_m1    ),  // 低bank请求就绪
    .bank_lo_addr       ( dbank1_lo_req_addr_m1   ),  // 低bank请求地址
    .bank_lo_id         ( dbank1_lo_req_id_m1     ),  // 低bank请求ID
    .bank_lo_wr         ( dbank1_lo_req_wr_m1     ),  // 低bank写使能
    .bank_lo_wdata      ( dbank1_lo_req_wdata_m1  ),  // 低bank写数据
    .bank_lo_wstrb      ( dbank1_lo_req_wstrb_m1  ),  // 低bank写字节使能
    .bank_lo_atop       ( dbank1_lo_req_atop_m1   ),  // 低bank原子操作类型
    // 高bank接口(延迟1周期)
    .bank_hi_vld        ( dbank1_hi_req_vld_m1    ),  // 高bank请求有效
    .bank_hi_rdy        ( dbank1_hi_req_rdy_m1    ),  // 高bank请求就绪
    .bank_hi_addr       ( dbank1_hi_req_addr_m1   ),  // 高bank请求地址
    .bank_hi_id         ( dbank1_hi_req_id_m1     ),  // 高bank请求ID
    .bank_hi_wr         ( dbank1_hi_req_wr_m1     ),  // 高bank写使能
    .bank_hi_wdata      ( dbank1_hi_req_wdata_m1  ),  // 高bank写数据
    .bank_hi_wstrb      ( dbank1_hi_req_wstrb_m1  ),  // 高bank写字节使能
    .bank_hi_atop       ( dbank1_hi_req_atop_m1   ),  // 高bank原子操作类型
    // Bank忙状态指示
    .bank_lo_busy       ( dbank1_lo_busy          ),  // 低bank忙状态
    .bank_hi_busy       ( dbank1_hi_busy          )   // 高bank忙状态
);

//=================================================================================
// DTCM1 Bank Instantiation - DTCM1存储器bank实例化
// 实现两个bank(lo和hi)以支持并行访问，提高存储器带宽
//=================================================================================

// DTCM1低bank实例 - 处理地址的低位部分
chunjun_tcu_bank #(
    .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
    .LSQID_W    ( ($clog2(6) + 1)          ),  // 加载存储队列ID位宽(6个LSU + 1)
    .DATA_W     ( 32                        ),  // 数据位宽
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W  ),  // RAM数据位宽
    .RAM_ADDR_W ( `CHUNJUN_DTCM1_RAM_ADDR_W ),  // RAM地址位宽
    .SLV_SPLIT_N( 2                         ),  // 从设备分割数量
    .ECC_EN     ( TCM_ECC_EN                ),  // ECC使能
    .ATOP_EN    ( DTCM_ATOP_EN              ),  // 原子操作使能
    .WAIT_EN    ( DTCM1_WAIT_EN             ),  // 等待使能
    .VBANK_N    ( 0                         )   // 虚拟bank数量
) u_dtcm1_bank_lo (
    // 时钟、复位和控制信号
    .clk                   ( clk                      ),  // 系统时钟
    .rst_n                 ( rst_n                    ),  // 低电平有效复位
    .csr_ecc_en            ( csr_ecc_en               ),  // CSR ECC使能
    // 刷新和取消信号
    .icu_flush             ( icu_tcu_flush_m2         ),  // ICU刷新(延迟2周期)
    .icu_cancel            ( icu_tcu_cancel_m2        ),  // ICU取消(延迟2周期)
    .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2 ),  // LSU取消(延迟2周期)
    .lsu_flush             ( lsu_tcu_flush_valid      ),  // LSU刷新有效
    .lsu_flush_id          ( lsu_tcu_flush_lsqid      ),  // LSU刷新队列ID
    .vpu_cancel            ( vpu_tcu_cancel_m2        ),  // VPU取消(延迟2周期)
    // Bank请求接口(延迟1周期)
    .bank_req_vld_m1       ( dbank1_lo_req_vld_m1     ),  // 请求有效
    .bank_req_rdy_m1       ( dbank1_lo_req_rdy_m1     ),  // 请求就绪
    .bank_req_addr_m1      ( dbank1_lo_req_addr_m1    ),  // 请求地址
    .bank_req_id_m1        ( dbank1_lo_req_id_m1      ),  // 请求ID
    .bank_req_wr_m1        ( dbank1_lo_req_wr_m1      ),  // 写使能
    .bank_req_wdata_m1     ( dbank1_lo_req_wdata_m1   ),  // 写数据
    .bank_req_wstrb_m1     ( dbank1_lo_req_wstrb_m1   ),  // 写字节使能
    .bank_req_atop_m1      ( dbank1_lo_req_atop_m1    ),  // 原子操作类型
    .bank_req_data_dest_m1 ( 2'b0                     ),  // 数据目标(固定为0)
    // 状态指示信号
    .into_partial_m1       ( dbank1_lo_into_partial_m1),  // 进入部分访问状态
    .into_atomic_m1        ( dbank1_lo_into_atomic_m1 ),  // 进入原子操作状态
    .bank_busy             ( dbank1_lo_busy           ),  // bank忙状态
    .bank_idle             ( dbank1_lo_idle           ),  // bank空闲状态
    // RAM接口(延迟1周期)
    .ram_cs_m1             ( dtcm1_ram_lo_cs          ),  // RAM片选
    .ram_wr_m1             ( dtcm1_ram_lo_wr          ),  // RAM写使能
    .ram_addr_m1           ( dtcm1_ram_lo_addr        ),  // RAM地址
    .ram_wen_m1            ( dtcm1_ram_lo_wen         ),  // RAM写使能(细粒度)
    .ram_wdata_m1          ( dtcm1_ram_lo_wdata       ),  // RAM写数据
    .ram_rdata_m2          ( dtcm1_rdata_lo           ),  // RAM读数据(延迟2周期)
    // 数据保持信号(用于原子操作)
    .hold_wdata            ( dbank1_hold_wdata_lo     ),  // 保持写数据
    .hold_wstrb            ( dbank1_hold_wstrb_lo     ),  // 保持写字节使能
    .hold_atop             ( dbank1_hold_atop_lo      ),  // 保持原子操作类型
    .hold_cmp_val          ( dbank1_hold_cmp_val      ),  // 保持比较值
    // Bank响应接口(延迟2周期)
    .bank_rsp_vld_m2       ( dbank1_lo_rsp_vld_m2     ),  // 响应有效
    .bank_rsp_id_m2        ( dbank1_lo_rsp_id_m2      ),  // 响应ID
    .bank_rsp_data_m2      ( dbank1_lo_rsp_data_m2    ),  // 响应数据
    .bank_rsp_se_m2        ( dbank1_lo_rsp_se_m2      ),  // 响应单比特错误
    .bank_rsp_de_m2        ( dbank1_lo_rsp_de_m2      ),  // 响应双比特错误
    .bank_rsp_data_dest_m2 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m2      ( dbank1_lo_rsp_addr_m2    ),  // 响应地址
    // Bank响应接口(延迟3周期)
    .bank_rsp_vld_m3       ( dbank1_lo_rsp_vld_m3     ),  // 响应有效
    .bank_rsp_id_m3        ( dbank1_lo_rsp_id_m3      ),  // 响应ID
    .bank_rsp_data_m3      ( dbank1_lo_rsp_data_m3    ),  // 响应数据
    .bank_rsp_se_m3        ( dbank1_lo_rsp_se_m3      ),  // 响应单比特错误
    .bank_rsp_de_m3        ( dbank1_lo_rsp_de_m3      ),  // 响应双比特错误
    .bank_rsp_data_dest_m3 (                          ),  // 响应数据目标(未连接)
    .bank_rsp_addr_m3      ( dbank1_lo_rsp_addr_m3    ),  // 响应地址
    // 原子操作状态(延迟3周期)
    .bank_atop_b_infly_m3  ( dbank1_lo_atop_b_infly_m3),  // 原子操作B进行中
    .bank_atop_r_infly_m3  ( dbank1_lo_atop_r_infly_m3),  // 原子操作R进行中
    // RAS(Return Address Stack)响应接口
    .bank_rsp_vld_ras      ( dbank1_lo_rsp_vld_ras    ),  // RAS响应有效
    .bank_rsp_id_ras       ( dbank1_lo_rsp_id_ras     ),  // RAS响应ID
    .bank_rsp_se_ras       ( dbank1_lo_rsp_se_ras     ),  // RAS响应单比特错误
    .bank_rsp_de_ras       ( dbank1_lo_rsp_de_ras     ),  // RAS响应双比特错误
    .bank_rsp_wr_ras       ( dbank1_lo_rsp_wr_ras     ),  // RAS响应写标志
    .bank_rsp_addr_ras     ( dbank1_lo_rsp_addr_ras   )   // RAS响应地址
);

// DTCM1高bank实例 - 处理地址的高位部分
chunjun_tcu_bank #(
    .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
    .LSQID_W    ( ($clog2(6) + 1)          ),  // 加载存储队列ID位宽(6个LSU + 1)
    .DATA_W     ( 32                        ),  // 数据位宽
    .RAM_DATA_W ( `CHUNJUN_DTCM_RAM_DATA_W  ),  // RAM数据位宽
    .RAM_ADDR_W ( `CHUNJUN_DTCM1_RAM_ADDR_W ),  // RAM地址位宽
    .SLV_SPLIT_N( 2                         ),  // 从设备分割数量
    .ECC_EN     ( TCM_ECC_EN                ),  // ECC使能
    .ATOP_EN    ( DTCM_ATOP_EN              ),  // 原子操作使能
    .WAIT_EN    ( DTCM1_WAIT_EN             ),  // 等待使能
    .VBANK_N    ( 0                         )   // 虚拟bank数量
) u_dtcm1_bank_hi (
    // 时钟、复位和控制信号
    .clk                   ( clk                      ),  // 系统时钟
    .rst_n                 ( rst_n                    ),  // 低电平有效复位
    .csr_ecc_en            ( csr_ecc_en               ),  // CSR ECC使能
    // 刷新和取消信号
    .icu_flush             ( icu_tcu_flush_m2         ),  // ICU刷新(延迟2周期)
    .icu_cancel            ( icu_tcu_cancel_m2        ),  // ICU取消(延迟2周期)
    .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2 ),  // LSU取消(延迟2周期)
    .lsu_flush             ( lsu_tcu_flush_valid      ),  // LSU刷新有效
    .lsu_flush_id          ( lsu_tcu_flush_lsqid      ),  // LSU刷新队列ID
    .vpu_cancel            ( vpu_tcu_cancel_m2        ),  // VPU取消(延迟2周期)
    // Bank请求接口(延迟1周期)
    .bank_req_vld_m1       ( dbank1_hi_req_vld_m1     ),  // Bank请求有效
    .bank_req_rdy_m1       ( dbank1_hi_req_rdy_m1     ),  // Bank请求就绪
    .bank_req_addr_m1      ( dbank1_hi_req_addr_m1    ),  // Bank请求地址
    .bank_req_id_m1        ( dbank1_hi_req_id_m1      ),  // Bank请求ID
    .bank_req_wr_m1        ( dbank1_hi_req_wr_m1      ),  // Bank写请求
    .bank_req_wdata_m1     ( dbank1_hi_req_wdata_m1   ),  // Bank写数据
    .bank_req_wstrb_m1     ( dbank1_hi_req_wstrb_m1   ),  // Bank写字节使能
    .bank_req_atop_m1      ( dbank1_hi_req_atop_m1    ),  // Bank原子操作类型
    .bank_req_data_dest_m1 ( 2'b0                     ),  // Bank数据目标(固定为0)
    // Bank状态信号
    .into_partial_m1       ( dbank1_hi_into_partial_m1),  // 进入部分写状态
    .into_atomic_m1        ( dbank1_hi_into_atomic_m1 ),  // 进入原子操作状态
    .bank_busy             ( dbank1_hi_busy           ),  // Bank忙状态
    .bank_idle             ( dbank1_hi_idle           ),  // Bank空闲状态
    // RAM接口(延迟1周期)
    .ram_cs_m1             ( dtcm1_ram_hi_cs          ),  // RAM片选信号
    .ram_wr_m1             ( dtcm1_ram_hi_wr          ),  // RAM写使能
    .ram_addr_m1           ( dtcm1_ram_hi_addr        ),  // RAM地址
    .ram_wen_m1            ( dtcm1_ram_hi_wen         ),  // RAM写使能(字节级)
    .ram_wdata_m1          ( dtcm1_ram_hi_wdata       ),  // RAM写数据
    .ram_rdata_m2          ( dtcm1_rdata_hi           ),  // RAM读数据(延迟2周期)
    // 保持信号接口
    .hold_wdata            ( dbank1_hold_wdata_hi     ),  // 保持的写数据
    .hold_wstrb            ( dbank1_hold_wstrb_hi     ),  // 保持的写字节使能
    .hold_atop             ( dbank1_hold_atop_hi      ),  // 保持的原子操作类型
    .hold_cmp_val          ( dbank1_hold_cmp_val      ),  // 保持的比较值
    // Bank响应接口(延迟2周期)
    .bank_rsp_vld_m2       ( dbank1_hi_rsp_vld_m2     ),  // Bank响应有效
    .bank_rsp_id_m2        ( dbank1_hi_rsp_id_m2      ),  // Bank响应ID
    .bank_rsp_data_m2      ( dbank1_hi_rsp_data_m2    ),  // Bank响应数据
    .bank_rsp_se_m2        ( dbank1_hi_rsp_se_m2      ),  // Bank响应系统错误
    .bank_rsp_de_m2        ( dbank1_hi_rsp_de_m2      ),  // Bank响应数据错误
    .bank_rsp_data_dest_m2 (                          ),  // Bank响应数据目标(未使用)
    .bank_rsp_addr_m2      ( dbank1_hi_rsp_addr_m2    ),  // Bank响应地址
    // Bank响应接口(延迟3周期)
    .bank_rsp_vld_m3       ( dbank1_hi_rsp_vld_m3     ),  // Bank响应有效
    .bank_rsp_id_m3        ( dbank1_hi_rsp_id_m3      ),  // Bank响应ID
    .bank_rsp_data_m3      ( dbank1_hi_rsp_data_m3    ),  // Bank响应数据
    .bank_rsp_se_m3        ( dbank1_hi_rsp_se_m3      ),  // Bank响应系统错误
    .bank_rsp_de_m3        ( dbank1_hi_rsp_de_m3      ),  // Bank响应数据错误
    .bank_rsp_data_dest_m3 (                          ),  // Bank响应数据目标(未使用)
    .bank_rsp_addr_m3      ( dbank1_hi_rsp_addr_m3    ),  // Bank响应地址
    // 原子操作状态接口(延迟3周期)
    .bank_atop_b_infly_m3  ( dbank1_hi_atop_b_infly_m3),  // Bank原子操作B进行中
    .bank_atop_r_infly_m3  ( dbank1_hi_atop_r_infly_m3),  // Bank原子操作R进行中
    // RAS(返回地址栈)接口
    .bank_rsp_vld_ras      ( dbank1_hi_rsp_vld_ras    ),  // Bank响应有效(RAS)
    .bank_rsp_id_ras       ( dbank1_hi_rsp_id_ras     ),  // Bank响应ID(RAS)
    .bank_rsp_se_ras       ( dbank1_hi_rsp_se_ras     ),  // Bank响应系统错误(RAS)
    .bank_rsp_de_ras       ( dbank1_hi_rsp_de_ras     ),  // Bank响应数据错误(RAS)
    .bank_rsp_wr_ras       ( dbank1_hi_rsp_wr_ras     ),  // Bank响应写标志(RAS)
    .bank_rsp_addr_ras     ( dbank1_hi_rsp_addr_ras   )   // Bank响应地址(RAS)
);

//=================================================================================
// DTCM1 Bank Hold Reg
//=================================================================================
// Hold wdata: 
// 1. partial write when ECC
// 2. atomic operation
if (TCM_ECC_EN || DTCM_ATOP_EN) begin: g_dtcm1_hold_wdata  //当ECC使能或原子操作使能时，保持写数据和写选通
 
  assign dbank1_into_partial_m1 = dbank1_lo_into_partial_m1 | dbank1_hi_into_partial_m1; //DTCM1进入部分写状态
  assign dbank1_into_atomic_m1  = dbank1_lo_into_atomic_m1  | dbank1_hi_into_atomic_m1; //DTCM1进入原子操作状态

  assign dbank1_hold_wdata_en   = dbank1_into_partial_m1 | dbank1_into_atomic_m1; //DTCM1保持写数据使能
  assign dbank1_hold_wdata_m1   = {dbank1_hi_req_wdata_m1[31:0], dbank1_lo_req_wdata_m1[31:0]}; //DTCM1保持写数据

  assign dbank1_hold_wstrb_en   = dbank1_into_partial_m1 | dbank1_into_atomic_m1;     //当ECC使能或原子操作使能时，保持写选通
  assign dbank1_hold_wstrb_m1   = {dbank1_hi_req_wstrb_m1, dbank1_lo_req_wstrb_m1};   //DTCM1保持写选通

  `WDFFER(dbank1_hold_wdata, dbank1_hold_wdata_m1, dbank1_hold_wdata_en, clk, rst_n) //DTCM1保持写数据
  `WDFFER(dbank1_hold_wstrb, dbank1_hold_wstrb_m1, dbank1_hold_wstrb_en, clk, rst_n)   //DTCM1保持写选通

  assign dbank1_hold_wdata_lo = dbank1_hold_wdata[31: 0]; //保持写数据的低32位
  assign dbank1_hold_wdata_hi = dbank1_hold_wdata[63:32]; //保持写数据的高32位

  assign dbank1_hold_wstrb_lo = dbank1_hold_wstrb[3:0]; //保持写选通的高4位
  assign dbank1_hold_wstrb_hi = dbank1_hold_wstrb[7:4]; //保持写选通的低4位

end else begin: g_dtcm1_no_hold_wdata
 
  assign dbank1_hold_wdata_lo = 32'b0; //当没有ECC或者原子操作时，不保持写数据
  assign dbank1_hold_wdata_hi = 32'b0; //当没有ECC或者原子操作时，不保持写数据

  assign dbank1_hold_wstrb_lo = 4'b0; //当没有ECC或者原子操作时，不保持写选通
  assign dbank1_hold_wstrb_hi = 4'b0; //当没有ECC或者原子操作时，不保持写选通
 
end

// Hold atop code
if (DTCM_ATOP_EN) begin: g_dtcm1_hold_atop //当DTCM1原子操作使能时，保持原子操作类型
 
  assign dbank1_lo_hold_atop_m1 = dbank1_lo_req_atop_m1; //保持原子操作类型的低6位
  assign dbank1_hi_hold_atop_m1 = dbank1_hi_req_atop_m1; //保持原子操作类型的高6位
  assign dbank1_atop_cmp_val_m1 = sbu_tcu_req_wdata[63:32]; //保持写数据的高32位

  `WDFFER(dbank1_hold_atop_lo, dbank1_lo_hold_atop_m1, dbank1_lo_into_atomic_m1, clk, rst_n) //生成保持原子操作类型的低6位
  `WDFFER(dbank1_hold_atop_hi, dbank1_hi_hold_atop_m1, dbank1_hi_into_atomic_m1, clk, rst_n) //生成保持原子操作类型的高6位
  `WDFFER(dbank1_hold_cmp_val, dbank1_atop_cmp_val_m1, dbank1_into_atomic_m1   , clk, rst_n) //生成保持写数据的高32位
 
end else begin: g_dtcm1_no_hold_atop

  assign dbank1_hold_atop_lo = 6'b0; //当没有原子操作时，不保持原子操作类型
  assign dbank1_hold_atop_hi = 6'b0; //当没有原子操作时，不保持原子操作类型
  assign dbank1_hold_cmp_val = 32'b0; //当没有原子操作时，不保持写数据
 
end

//**********************************************************************************************//
`else   // CHUNJUN_SUPPORT_DTCM1
//**********************************************************************************************//
assign dtcm1_icu_req_rdy    = 1'b0;  //nouse
assign dtcm1_lsu_req_rdy[0] = 1'b0;//nouse
assign dtcm1_lsu_req_rdy[1] = 1'b0;//nouse
assign dtcm1_sbu_req_rdy    = 1'b0;//nouse
assign dtcm1_slv_req_rdy    = 1'b0;//nouse
 
assign dbank1_lo_rsp_vld_m2    = 1'b0;//nouse
assign dbank1_lo_rsp_id_m2     = {TCM_ID_W{1'b0}};//nouse
assign dbank1_lo_rsp_data_m2   = 32'b0;//nouse
assign dbank1_lo_rsp_se_m2     = 1'b0;//nouse
assign dbank1_lo_rsp_de_m2     = 1'b0;//nouse
assign dbank1_lo_rsp_addr_m2   = 19'b0;//nouse
assign dbank1_lo_rsp_vld_m3    = 1'b0;//nouse
assign dbank1_lo_rsp_id_m3     = {TCM_ID_W{1'b0}};//nouse
assign dbank1_lo_rsp_data_m3   = 32'b0;//nouse
assign dbank1_lo_rsp_se_m3     = 1'b0;//nouse
assign dbank1_lo_rsp_de_m3     = 1'b0;//nouse
assign dbank1_lo_rsp_addr_m3   = 20'b0;//nouse
assign dbank1_lo_atop_b_infly_m3 = 1'b0;//nouse
assign dbank1_lo_atop_r_infly_m3 = 1'b0;//nouse
assign dbank1_lo_rsp_vld_ras   = 1'b0;//nouse
assign dbank1_lo_rsp_id_ras    = {TCM_ID_W{1'b0}};//nouse
assign dbank1_lo_rsp_se_ras    = 1'b0;//nouse
assign dbank1_lo_rsp_de_ras    = 1'b0;//nouse
assign dbank1_lo_rsp_wr_ras    = 1'b0;//nouse
assign dbank1_lo_rsp_addr_ras  = 20'b0;//nouse

assign dbank1_hi_rsp_vld_m2    = 1'b0;//nouse
assign dbank1_hi_rsp_id_m2     = {TCM_ID_W{1'b0}};//nouse
assign dbank1_hi_rsp_data_m2   = 32'b0;//nouse
assign dbank1_hi_rsp_se_m2     = 1'b0;//nouse
assign dbank1_hi_rsp_de_m2     = 1'b0;//nouse
assign dbank1_hi_rsp_addr_m2   = 20'b0;//nouse
assign dbank1_hi_rsp_vld_m3    = 1'b0;//nouse
assign dbank1_hi_rsp_id_m3     = {TCM_ID_W{1'b0}};//nouse
assign dbank1_hi_rsp_data_m3   = 32'b0;//nouse
assign dbank1_hi_rsp_se_m3     = 1'b0;//nouse
assign dbank1_hi_rsp_de_m3     = 1'b0;//nouse
assign dbank1_hi_rsp_addr_m3   = 20'b0;//nouse
assign dbank1_hi_atop_b_infly_m3 = 1'b0;//nouse
assign dbank1_hi_atop_r_infly_m3 = 1'b0;//nouse
assign dbank1_hi_rsp_vld_ras   = 1'b0;//nouse
assign dbank1_hi_rsp_id_ras    = {TCM_ID_W{1'b0}};//nouse
assign dbank1_hi_rsp_se_ras    = 1'b0;//nouse
assign dbank1_hi_rsp_de_ras    = 1'b0;//nouse
assign dbank1_hi_rsp_wr_ras    = 1'b0;//nouse
assign dbank1_hi_rsp_addr_ras  = 20'b0;//nouse
//**********************************************************************************************//
`endif  // CHUNJUN_SUPPORT_DTCM1
//**********************************************************************************************//


//**********************************************************************************************//
`ifdef CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//
//=================================================================================
// VTCM Arbiter - VTCM仲裁器
// 功能：管理多个主设备(LSU、SBU、SLV、VPU)对VTCM的访问请求，进行仲裁并路由到相应的bank
// 支持向量扩展指令集时启用
//=================================================================================
chunjun_tcu_vtcmarb #(
  .ID_W       (TCM_ID_W),                                    // 请求ID位宽
  .RAM_DATA_W (`CHUNJUN_VTCM_RAM_DATA_W),                   // VTCM RAM数据位宽
  .BANK_N     (`CHUNJUN_VTCM_BANK_N)                        // VTCM bank数量
) u_tcu_vtcm_arb(
  // 时钟和复位信号
  .clk                ( clk   ),                             // 系统时钟
  .rst_n              ( rst_n ),                             // 低电平有效复位
  
  // LSU(加载存储单元)接口
  .lsu_vtcm_req_vld   ( lsu_vtcm_req_vld       ),           // LSU VTCM请求有效
  .vtcm_lsu_req_rdy   ( vtcm_lsu_req_rdy       ),           // VTCM LSU请求就绪
  .lsu_vtcm_req_addr  ( lsu_tcu_ld_req_addr_m1 ),           // LSU VTCM请求地址(延迟1周期)
  .lsu_vtcm_req_id    ( aln_req_id_lsu         ),           // LSU VTCM请求ID
  
  // SBU(系统总线单元)接口
  .sbu_vtcm_req_vld   ( sbu_vtcm_req_vld       ),           // SBU VTCM请求有效
  .vtcm_sbu_req_rdy   ( vtcm_sbu_req_rdy       ),           // VTCM SBU请求就绪
  .sbu_vtcm_req_addr  ( sbu_tcu_req_addr       ),           // SBU VTCM请求地址
  .sbu_vtcm_req_id    ( aln_req_id_sbu         ),           // SBU VTCM请求ID
  .sbu_vtcm_req_wdata ( sbu_tcu_req_wdata      ),           // SBU VTCM写数据
  .sbu_vtcm_req_wstrb ( sbu_tcu_req_wstrb      ),           // SBU VTCM写字节使能
  
  // SLV(从设备，通过BMU访问)接口
  .slv_vtcm_req_vld   ( slv_vtcm_req_vld       ),           // SLV VTCM请求有效
  .vtcm_slv_req_rdy   ( vtcm_slv_req_rdy       ),           // VTCM SLV请求就绪
  .slv_vtcm_req_addr  ( bmu_req_addr_mux       ),           // SLV VTCM请求地址(多路复用)
  .slv_vtcm_req_id    ( aln_req_id_slv         ),           // SLV VTCM请求ID
  .slv_vtcm_req_wr    ( bmu_req_wr_mux         ),           // SLV VTCM写请求(多路复用)
  .slv_vtcm_req_wdata ( bmu_req_wdata_mux      ),           // SLV VTCM写数据(多路复用)
  .slv_vtcm_req_wstrb ( bmu_req_wstrb_mux      ),           // SLV VTCM写字节使能(多路复用)
  
  // VPU(向量处理单元)接口
  .vpu_vtcm_req_vld   ( vpu_vtcu_req_vld_m1    ),           // VPU VTCM请求有效(延迟1周期)
  .vtcm_vpu_req_rdy   ( vtcu_vpu_req_rdy_m1    ),           // VTCM VPU请求就绪(延迟1周期)
  .vpu_vtcm_req_wr    ( vpu_vtcu_req_wr_m1     ),           // VPU VTCM写请求(延迟1周期)
  .vpu_vtcm_req_id    ( aln_req_id_vtcm        ),           // VPU VTCM请求ID
  .vpu_vtcm_req_addr  ( vpu_vtcu_req_addr_m1   ),           // VPU VTCM请求地址(延迟1周期)
  .vpu_vtcm_req_wdata ( vpu_vtcu_req_wdata_m1  ),           // VPU VTCM写数据(延迟1周期)
  .vpu_vtcm_req_wstrb ( vpu_vtcu_req_wstrb_m1  ),           // VPU VTCM写字节使能(延迟1周期)
  
  // Bank接口(延迟1周期)
  .vbank_vld          ( vbank_req_vld_m1       ),           // Bank请求有效
  .vbank_rdy          ( vbank_req_rdy_m1       ),           // Bank请求就绪
  .vbank_addr         ( vbank_req_addr_m1      ),           // Bank请求地址
  .vbank_id           ( vbank_req_id_m1        ),           // Bank请求ID
  .vbank_wr           ( vbank_req_wr_m1        ),           // Bank写请求
  .vbank_wdata        ( vbank_req_wdata_m1     ),           // Bank写数据
  .vbank_wstrb        ( vbank_req_wstrb_m1     ),           // Bank写字节使能
  .vbank_dest         ( vbank_req_dest_m1      ),           // Bank数据目标
  .bank_busy          ( vbank_busy             )            // Bank忙状态
);

//=================================================================================
// VTCM Bank Instantiation - VTCM Bank实例化
// 功能：实例化多个VTCM bank模块，实现向量内存的并行访问
// 使用generate循环创建多个bank实例，每个bank处理不同的地址范围
//=================================================================================
for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_bank
 
  // VTCM Bank实例 - 处理向量内存的第i个bank
  chunjun_tcu_bank #(
      .ID_W       ( TCM_ID_W                  ),  // 请求ID位宽
      .LSQID_W    ( ($clog2(6) + 1)          ),  // 加载存储队列ID位宽(6个LSU + 1)
      .DATA_W     ( 32                        ),  // 数据位宽
      .RAM_DATA_W ( `CHUNJUN_VTCM_RAM_DATA_W  ),  // VTCM RAM数据位宽
      .RAM_ADDR_W ( `CHUNJUN_VTCM_RAM_ADDR_W  ),  // VTCM RAM地址位宽
      .SLV_SPLIT_N( 2                         ),  // 从设备分割数量
      .ECC_EN     ( TCM_ECC_EN                ),  // ECC使能
      .ATOP_EN    ( 0                         ),  // 原子操作使能(VTCM不支持原子操作)
      .WAIT_EN    ( VTCM_WAIT_EN              ),  // 等待使能
      .VBANK_N    ( `CHUNJUN_VTCM_BANK_N      )   // 虚拟bank数量
  ) u_vtcm_bank (
      // 时钟、复位和控制信号
      .clk                   ( clk                       ),  // 系统时钟
      .rst_n                 ( rst_n                     ),  // 低电平有效复位
      .csr_ecc_en            ( csr_ecc_en                ),  // CSR ECC使能
      
      // 刷新和取消信号
      .icu_flush             ( 1'b0                      ),  // ICU刷新(VTCM不使用ICU)
      .icu_cancel            ( 1'b0                      ),  // ICU取消(VTCM不使用ICU)
      .lsu_cancel            ( lsu_tcu_ld_req_cancel_m2  ),  // LSU取消(延迟2周期)
      .lsu_flush             ( lsu_tcu_flush_valid       ),  // LSU刷新有效
      .lsu_flush_id          ( lsu_tcu_flush_lsqid       ),  // LSU刷新队列ID
      .vpu_cancel            ( 2'b0                      ),  // VPU取消(固定为0)
      
      // Bank请求接口(延迟1周期)
      .bank_req_vld_m1       ( vbank_req_vld_m1[i]       ),  // Bank请求有效
      .bank_req_rdy_m1       ( vbank_req_rdy_m1[i]       ),  // Bank请求就绪
      .bank_req_addr_m1      ( vbank_req_addr_m1[i]      ),  // Bank请求地址
      .bank_req_id_m1        ( vbank_req_id_m1[i]        ),  // Bank请求ID
      .bank_req_wr_m1        ( vbank_req_wr_m1[i]        ),  // Bank写请求
      .bank_req_wdata_m1     ( vbank_req_wdata_m1[i]     ),  // Bank写数据
      .bank_req_wstrb_m1     ( vbank_req_wstrb_m1[i]     ),  // Bank写字节使能
      .bank_req_atop_m1      ( 6'b0                      ),  // Bank原子操作类型(固定为0)
      .bank_req_data_dest_m1 ( vbank_req_dest_m1[i]      ),  // Bank数据目标
      
      // Bank状态信号
      .into_partial_m1       ( vbank_into_partial_m1[i]  ),  // 进入部分写状态
      .into_atomic_m1        (                           ),  // 进入原子操作状态(未使用)
      .bank_busy             ( vbank_busy[i]             ),  // Bank忙状态
      .bank_idle             ( vbank_idle[i]             ),  // Bank空闲状态
      
      // RAM接口(延迟1周期)
      .ram_cs_m1             ( vtcm_ram_cs[i]            ),  // RAM片选信号
      .ram_wr_m1             ( vtcm_ram_wr[i]            ),  // RAM写使能
      .ram_addr_m1           ( vtcm_ram_addr[i]          ),  // RAM地址
      .ram_wen_m1            ( vtcm_ram_wen[i]           ),  // RAM写使能(字节级)
      .ram_wdata_m1          ( vtcm_ram_wdata[i]         ),  // RAM写数据
      .ram_rdata_m2          ( vtcm_rdata[i]             ),  // RAM读数据(延迟2周期)
      
      // 保持信号接口
      .hold_wdata            ( vbank_hold_wdata[i]       ),  // 保持的写数据
      .hold_wstrb            ( vbank_hold_wstrb[i]       ),  // 保持的写字节使能
      .hold_atop             ( 6'b0                      ),  // 保持的原子操作类型(固定为0)
      .hold_cmp_val          ( 32'b0                     ),  // 保持的比较值(固定为0)
      
      // Bank响应接口(延迟2周期)
      .bank_rsp_vld_m2       ( vbank_rsp_vld_m2[i]       ),  // Bank响应有效
      .bank_rsp_id_m2        ( vbank_rsp_id_m2[i]        ),  // Bank响应ID
      .bank_rsp_data_m2      ( vbank_rsp_data_m2[i]      ),  // Bank响应数据
      .bank_rsp_se_m2        ( vbank_rsp_se_m2[i]        ),  // Bank响应系统错误
      .bank_rsp_de_m2        ( vbank_rsp_de_m2[i]        ),  // Bank响应数据错误
      .bank_rsp_data_dest_m2 ( vbank_rsp_data_dest_m2[i] ),  // Bank响应数据目标
      .bank_rsp_addr_m2      ( vbank_rsp_addr_m2[i]      ),  // Bank响应地址
      
      // Bank响应接口(延迟3周期)
      .bank_rsp_vld_m3       ( vbank_rsp_vld_m3[i]       ),  // Bank响应有效
      .bank_rsp_id_m3        ( vbank_rsp_id_m3[i]        ),  // Bank响应ID
      .bank_rsp_data_m3      ( vbank_rsp_data_m3[i]      ),  // Bank响应数据
      .bank_rsp_se_m3        ( vbank_rsp_se_m3[i]        ),  // Bank响应系统错误
      .bank_rsp_de_m3        ( vbank_rsp_de_m3[i]        ),  // Bank响应数据错误
      .bank_rsp_data_dest_m3 ( vbank_rsp_data_dest_m3[i] ),  // Bank响应数据目标
      .bank_rsp_addr_m3      ( vbank_rsp_addr_m3[i]      ),  // Bank响应地址
      
      // 原子操作状态接口(延迟3周期)
      .bank_atop_b_infly_m3  (                           ),  // Bank原子操作B进行中(未使用)
      .bank_atop_r_infly_m3  (                           ),  // Bank原子操作R进行中(未使用)
      
      // RAS(返回地址栈)接口
      .bank_rsp_vld_ras      ( vbank_rsp_vld_ras[i]      ),  // Bank响应有效(RAS)
      .bank_rsp_id_ras       ( vbank_rsp_id_ras[i]       ),  // Bank响应ID(RAS)
      .bank_rsp_se_ras       ( vbank_rsp_se_ras[i]       ),  // Bank响应系统错误(RAS)
      .bank_rsp_de_ras       ( vbank_rsp_de_ras[i]       ),  // Bank响应数据错误(RAS)
      .bank_rsp_wr_ras       ( vbank_rsp_wr_ras[i]       ),  // Bank响应写标志(RAS)
      .bank_rsp_addr_ras     ( vbank_rsp_addr_ras[i]     )   // Bank响应地址(RAS)
  );

end

//=================================================================================
// VTCM Bank Hold Reg
//=================================================================================
if (TCM_ECC_EN) begin: g_vtcm_hold_reg //当ECC使能时，保持写数据和写选通
 
  for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_bank_hold_reg

    `WDFFER(vbank_hold_wdata[i], vbank_req_wdata_m1[i][31:0], vbank_into_partial_m1[i], clk, rst_n) //当进入部分写状态时，保持写数据
    `WDFFER(vbank_hold_wstrb[i], vbank_req_wstrb_m1[i]      , vbank_into_partial_m1[i], clk, rst_n) //当进入部分写状态时，保持写选通
 
  end

end else begin: g_itcm_noecc
 
  assign vbank_hold_wdata = {`CHUNJUN_VTCM_BANK_N{32'b0}}; //当没有ECC时，不保持写数据
  assign vbank_hold_wstrb = {`CHUNJUN_VTCM_BANK_N{4'b0}}; //当没有ECC时，不保持写选通
 
end

//=================================================================================
// VTCM Rsp
//=================================================================================
for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_rsp_vld_vec //生成vbank的响应有效信号

  assign vbank_lsu0_rsp_vld_m2_oh[i] = vbank_rsp_vld_m2[i] & (vbank_rsp_id_m2[i][TCM_ID_W-1-:4] == EXT_ID_LSU0); //vbank的访问来源是LSU0
  assign vbank_lsu1_rsp_vld_m2_oh[i] = vbank_rsp_vld_m2[i] & (vbank_rsp_id_m2[i][TCM_ID_W-1-:4] == EXT_ID_LSU1); //vbank的访问来源是LSU1
  assign vbank_lsu0_rsp_vld_m3_oh[i] = vbank_rsp_vld_m3[i] & (vbank_rsp_id_m3[i][TCM_ID_W-1-:4] == EXT_ID_LSU0); //vbank的访问来源是LSU0
  assign vbank_lsu1_rsp_vld_m3_oh[i] = vbank_rsp_vld_m3[i] & (vbank_rsp_id_m3[i][TCM_ID_W-1-:4] == EXT_ID_LSU1); //vbank的访问来源是LSU1

  assign vbank_sbu_rsp_vld_m3_vec[i] = vbank_rsp_vld_m3[i] & (vbank_rsp_id_m3[i][TCM_ID_W-1-:4] == EXT_ID_SBU); //vbank的访问来源是SBU
  assign vbank_slv_rsp_vld_m3_vec[i] = vbank_rsp_vld_m3[i] & (vbank_rsp_id_m3[i][TCM_ID_W-1-:4] == EXT_ID_SLV); //vbank的访问来源是SLV

end
 
//----------------------------
// lsu rsp
//----------------------------
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(32      )) u_aomux_v_lsu0_rsp_data_m2 (.data_arr(vbank_rsp_data_m2), .sel_in_onehot0(vbank_lsu0_rsp_vld_m2_oh), .data_sel(vbank_lsu0_rsp_data_m2)); //选择vbank的访问来源是LSU0的响应数据， 32位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(32      )) u_aomux_v_lsu1_rsp_data_m2 (.data_arr(vbank_rsp_data_m2), .sel_in_onehot0(vbank_lsu1_rsp_vld_m2_oh), .data_sel(vbank_lsu1_rsp_data_m2)); //选择vbank的访问来源是LSU1的响应数据， 32位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_v_lsu0_rsp_id_m2   (.data_arr(vbank_rsp_id_m2  ), .sel_in_onehot0(vbank_lsu0_rsp_vld_m2_oh), .data_sel(vbank_lsu0_rsp_id_m2  )); //选择vbank的访问来源是LSU0的响应id， TCM_ID_W位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_v_lsu1_rsp_id_m2   (.data_arr(vbank_rsp_id_m2  ), .sel_in_onehot0(vbank_lsu1_rsp_vld_m2_oh), .data_sel(vbank_lsu1_rsp_id_m2  )); //选择vbank的访问来源是LSU1的响应id， TCM_ID_W位

wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_v_lsu0_rsp_id_m3   (.data_arr(vbank_rsp_id_m3  ), .sel_in_onehot0(vbank_lsu0_rsp_vld_m3_oh), .data_sel(vbank_lsu0_rsp_id_m3  )); //选择vbank的访问来源是LSU0的响应id， TCM_ID_W位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_v_lsu1_rsp_id_m3   (.data_arr(vbank_rsp_id_m3  ), .sel_in_onehot0(vbank_lsu1_rsp_vld_m3_oh), .data_sel(vbank_lsu1_rsp_id_m3  )); //选择vbank的访问来源是LSU1的响应id， TCM_ID_W位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(1       )) u_aomux_v_lsu0_rsp_se_m3   (.data_arr(vbank_rsp_se_m3  ), .sel_in_onehot0(vbank_lsu0_rsp_vld_m3_oh), .data_sel(vbank_lsu0_rsp_se_m3  )); //选择vbank的访问来源是LSU0的响应se， 1位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(1       )) u_aomux_v_lsu1_rsp_se_m3   (.data_arr(vbank_rsp_se_m3  ), .sel_in_onehot0(vbank_lsu1_rsp_vld_m3_oh), .data_sel(vbank_lsu1_rsp_se_m3  )); //选择vbank的访问来源是LSU1的响应se， 1位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(1       )) u_aomux_v_lsu0_rsp_de_m3   (.data_arr(vbank_rsp_de_m3  ), .sel_in_onehot0(vbank_lsu0_rsp_vld_m3_oh), .data_sel(vbank_lsu0_rsp_de_m3  )); //选择vbank的访问来源是LSU0的响应de， 1位
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(1       )) u_aomux_v_lsu1_rsp_de_m3   (.data_arr(vbank_rsp_de_m3  ), .sel_in_onehot0(vbank_lsu1_rsp_vld_m3_oh), .data_sel(vbank_lsu1_rsp_de_m3  )); //选择vbank的访问来源是LSU1的响应de， 1位

//----------------------------
// sbu rsp
//----------------------------
// sbu should not sent atop req to vtcm
//找到首个为0的位置，//例如0000: 0, 0001: 1, 0010: 0, 0011: 2
wing_cbb_lzc #(.WIDTH(`CHUNJUN_VTCM_BANK_N), .DIRECTION(0), .INVERT(1)) u_vbank_sbu_vld_first (.vec_i(vbank_sbu_rsp_vld_m3_vec), .cnt_o(vbank_sbu_rsp_vld_first), .empty_o ( ));    //找到首个为0的位置，0000: 0, 0001: 1, 0010: 0, 0011: 2
wing_cbb_aomux_idx #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_vbank_sbu_rsp_id (.data_arr(vbank_rsp_id_m3), .sel_idx(vbank_sbu_rsp_vld_first),.data_sel(vbank_sbu_rsp_id_m3)); //选择vbank的访问来源是SBU的响应id， TCM_ID_W位

assign vbank_sbu_rsp_de_m3 = |vbank_rsp_de_m3; //当vbank的响应de有效时，将vbank的响应de赋值给vbank_sbu_rsp_de_m3

//----------------------------
// slv rsp
//---------------------------
wing_cbb_lzc #(.WIDTH(`CHUNJUN_VTCM_BANK_N), .DIRECTION(0), .INVERT(1)) u_vbank_slv_vld_m3_first (.vec_i(vbank_slv_rsp_vld_m3_vec), .cnt_o(vbank_slv_rsp_vld_first), .empty_o ( )); //找到首个为0的位置，0000: 0, 0001: 1, 0010: 0, 0011: 2
wing_cbb_aomux_idx #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_vbank_slv_rsp_id (.data_arr(vbank_rsp_id_m3), .sel_idx(vbank_slv_rsp_vld_first),.data_sel(vbank_slv_rsp_id_m3)); //选择vbank的访问来源是SLV的响应id， TCM_ID_W位

assign vbank_slv_rsp_de_m3 = |vbank_rsp_de_m3; //当vbank的响应de有效时，将vbank的响应de赋值给vbank_slv_rsp_de_m3

vtcu_bank_router_gather #(   //将vbank的响应数据通过重排赋值给vbank_slv_rsp_data_m3，64位
  .BANK_N       ( `CHUNJUN_VTCM_BANK_N ),  //输入的bank数量
  .DATA_W       ( 64                   )  //输入的响应数据位宽
) u_slv_router_gather (
  .rsp_vld           ( vbank_rsp_vld_m3       ),  //输入的使能信号
  .rsp_rdata         ( vbank_rsp_data_m3      ),  //输入的响应数据
  .rsp_rdata_dest_oh ( vbank_rsp_data_dest_m3 ),  //输入的响应数据的排序信号
  .origin_rdata      ( vbank_slv_rsp_data_m3  )   //将vbank的响应数据通过重排赋值给vbank_slv_rsp_data_m3，64位
);

//**********************************************************************************************//
`else  // CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//
assign vtcm_lsu_req_rdy = 2'b0; //no use
assign vtcm_sbu_req_rdy = 1'b0; //no use
assign vtcm_slv_req_rdy = 1'b0; //no use

assign vbank_lsu0_rsp_vld_m2_oh = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use
assign vbank_lsu1_rsp_vld_m2_oh = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use
assign vbank_lsu0_rsp_vld_m3_oh = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use
assign vbank_lsu1_rsp_vld_m3_oh = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use
assign vbank_sbu_rsp_vld_m3_vec = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use
assign vbank_slv_rsp_vld_m3_vec = {`CHUNJUN_VTCM_BANK_N{1'b0}}; //no use

assign vbank_lsu0_rsp_data_m2 = 32'b0; //no use
assign vbank_lsu1_rsp_data_m2 = 32'b0; //no use
assign vbank_lsu0_rsp_id_m2   = {TCM_ID_W{1'b0}}; //no use
assign vbank_lsu1_rsp_id_m2   = {TCM_ID_W{1'b0}}; //no use
assign vbank_lsu0_rsp_id_m3   = {TCM_ID_W{1'b0}}; //no use
assign vbank_lsu1_rsp_id_m3   = {TCM_ID_W{1'b0}}; //no use
assign vbank_lsu0_rsp_se_m3   = 1'b0; //no use
assign vbank_lsu1_rsp_se_m3   = 1'b0; //no use
assign vbank_lsu0_rsp_de_m3   = 1'b0; //no use
assign vbank_lsu1_rsp_de_m3   = 1'b0; //no use
 
assign vbank_sbu_rsp_id_m3    = {TCM_ID_W{1'b0}}; //no use
assign vbank_sbu_rsp_de_m3    = 1'b0; //no use

assign vbank_slv_rsp_id_m3    = {TCM_ID_W{1'b0}}; //no use
assign vbank_slv_rsp_de_m3    = 1'b0; //no use
assign vbank_slv_rsp_data_m3  = {`CHUNJUN_SBUS_DATA_W{1'b0}}; //no use
//**********************************************************************************************//
`endif  // CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//


//=================================================================================
// Response Interface
//=================================================================================
//--------------------------------------------------------
// ICU response at M2 stage, without ecc correction.
// 4'b0000 - ICU
//--------------------------------------------------------
// icu flush:
//   NO_TCM_WAIT : no rsp_m2
//      TCM_WAIT : no rsp_m2
//
// icu cancel:
//   NO_TCM_WAIT : no rsp_m2
//      TCM_WAIT :    rsp_m2
//
// (rsp_m2 here we talking about means the rsp happens as same time as the flush/cancel)
// //当来自ITCM1（Data TC）的响应有效时, 且路由信息为ICU【ID的高位4位】，且没有取消或刷新信号时，响应ICU的请求
assign icu_rsp_vld_m2 [MUX_ICU_ITCM ] = ibank_rsp_vld_m2 & (ibank_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_ICU) & ~(icu_tcu_cancel_m2 | icu_tcu_flush_m2); 
//当来自DTCM0（Data TCM Bank 0）的响应有效时, 且路由信息为ICU【ID的高位4位】，且没有取消或刷新信号时，响应ICU的请求
assign icu_rsp_vld_m2 [MUX_ICU_DTCM0] = dbank0_lo_rsp_vld_m2 & (dbank0_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_ICU) & ~(icu_tcu_cancel_m2 | icu_tcu_flush_m2);
//当来自DTCM1（Data TCM Bank 1）的响应有效时, 且路由信息为ICU【ID的高位4位】，且没有取消或刷新信号时，响应ICU的请求
assign icu_rsp_vld_m2 [MUX_ICU_DTCM1] = dbank1_lo_rsp_vld_m2 & (dbank1_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_ICU) & ~(icu_tcu_cancel_m2 | icu_tcu_flush_m2);

assign icu_rsp_data_m2[MUX_ICU_ITCM ] = ibank_rsp_data_m2; //ITCM的响应数据直接赋值给ICU
assign icu_rsp_data_m2[MUX_ICU_DTCM0] = {dbank0_hi_rsp_data_m2, dbank0_lo_rsp_data_m2}; //DTCM0的响应数据拼接赋值给ICU
assign icu_rsp_data_m2[MUX_ICU_DTCM1] = {dbank1_hi_rsp_data_m2, dbank1_lo_rsp_data_m2}; //DTCM1的响应数据拼接赋值给ICU

assign icu_rsp_id_m2  [MUX_ICU_ITCM ] = ibank_rsp_id_m2    [$clog2(4)-1:0]; //ITCM的响应ID直接赋值给ICU
assign icu_rsp_id_m2  [MUX_ICU_DTCM0] = dbank0_lo_rsp_id_m2[$clog2(4)-1:0]; //DTCM0的响应ID直接赋值给ICU
assign icu_rsp_id_m2  [MUX_ICU_DTCM1] = dbank1_lo_rsp_id_m2[$clog2(4)-1:0]; //DTCM1的响应ID直接赋值给ICU

assign tcu_icu_rsp_vld_m2 = |icu_rsp_vld_m2; //选出返回ICU的vld信号

wing_cbb_aomux #(.NUM(3), .WIDTH(64                )) u_aomux_icu_rsp_data (.data_arr(icu_rsp_data_m2), .sel_in_onehot0(icu_rsp_vld_m2), .data_sel(tcu_icu_rsp_data_m2)); //选出返回ICU的数据
wing_cbb_aomux #(.NUM(3), .WIDTH($clog2(4))) u_aomux_icu_rsp_id_m2(.data_arr(icu_rsp_id_m2  ), .sel_in_onehot0(icu_rsp_vld_m2), .data_sel(tcu_icu_rsp_id_m2  ));  //选出返回ICU的id

//选出返回ICU的vld信号，选出返回DTCM0的vld信号，选出返回DTCM1的vld信号
assign icu_rsp_vld_m3 [MUX_ICU_ITCM ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_ICU); //ITCM的vld信号
assign icu_rsp_vld_m3 [MUX_ICU_DTCM0] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_ICU); //DTCM0的低位返回ICU的vld信号
assign icu_rsp_vld_m3 [MUX_ICU_DTCM1] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_ICU); //DTCM1的低位返回ICU的vld信号

//选出返回ICU的id，选出返回DTCM0的id，选出返回DTCM1的id
assign icu_rsp_id_m3  [MUX_ICU_ITCM ] = ibank_rsp_id_m3    [$clog2(4)-1:0]; //ITCM的id
assign icu_rsp_id_m3  [MUX_ICU_DTCM0] = dbank0_lo_rsp_id_m3[$clog2(4)-1:0]; //DTCM0的低位返回ICU的id
assign icu_rsp_id_m3  [MUX_ICU_DTCM1] = dbank1_lo_rsp_id_m3[$clog2(4)-1:0]; //DTCM1的低位返回ICU的id
 
//只要存在返回m3的ICU的vld信号，则返回ICU的vld信号有效
assign tcu_icu_rsp_vld_m3 = |icu_rsp_vld_m3;

wing_cbb_aomux #(.NUM(3), .WIDTH($clog2(4))) u_aomux_icu_rsp_id_m3(.data_arr(icu_rsp_id_m3), .sel_in_onehot0(icu_rsp_vld_m3), .data_sel(tcu_icu_rsp_id_m3));

assign icu_rsp_se_m3[MUX_ICU_ITCM ] = ibank_rsp_se_m3 & ~(ibank_rsp_de_m3);  //ITCM的se信号
assign icu_rsp_se_m3[MUX_ICU_DTCM0] = (dbank0_hi_rsp_se_m3 | dbank0_lo_rsp_se_m3) & ~(dbank0_hi_rsp_de_m3 | dbank0_lo_rsp_de_m3); //DTCM0的se信号
assign icu_rsp_se_m3[MUX_ICU_DTCM1] = (dbank1_hi_rsp_se_m3 | dbank1_lo_rsp_se_m3) & ~(dbank1_hi_rsp_de_m3 | dbank1_lo_rsp_de_m3); //DTCM1的se信号

assign icu_rsp_de_m3[MUX_ICU_ITCM ] = ibank_rsp_de_m3; //ITCM的de信号
assign icu_rsp_de_m3[MUX_ICU_DTCM0] = dbank0_hi_rsp_de_m3 | dbank0_lo_rsp_de_m3; //DTCM0的de信号
assign icu_rsp_de_m3[MUX_ICU_DTCM1] = dbank1_hi_rsp_de_m3 | dbank1_lo_rsp_de_m3; //DTCM1的de信号

wing_cbb_aomux #(.NUM(3), .WIDTH(1)) u_aomux_icu_rsp_se_m3(.data_arr(icu_rsp_se_m3), .sel_in_onehot0(icu_rsp_vld_m3), .data_sel(tcu_icu_rsp_replay_m3)); //选出返回ICU的se信号
wing_cbb_aomux #(.NUM(3), .WIDTH(1)) u_aomux_icu_rsp_de_m3(.data_arr(icu_rsp_de_m3), .sel_in_onehot0(icu_rsp_vld_m3), .data_sel(tcu_icu_rsp_raserr_m3)); //选出返回ICU的de信号

//--------------------------------------------------------
// LSU response at M2 stage, without ecc correction.
// 4'b0001 - LSU[0]
// 4'b0101 - LSU[1]
//--------------------------------------------------------
// lsu cancel:
//   NO_TCM_WAIT : no rsp_m2
//      TCM_WAIT :    rsp_m2
//
// (rsp_m2 here we talking about means the rsp happens as same time as the flush/cancel)
assign lsu0_rsp_vld_m2 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_vld_m2 & (dbank0_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU0) & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu0_rsp_vld_m2 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_vld_m2 & (dbank0_hi_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU0) & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu1_rsp_vld_m2 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_vld_m2 & (dbank0_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU1) & ~lsu_tcu_ld_req_cancel_m2[1];
assign lsu1_rsp_vld_m2 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_vld_m2 & (dbank0_hi_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU1) & ~lsu_tcu_ld_req_cancel_m2[1];

assign lsu0_rsp_vld_m2 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_vld_m2 & (dbank1_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU0) & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu0_rsp_vld_m2 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_vld_m2 & (dbank1_hi_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU0) & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu1_rsp_vld_m2 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_vld_m2 & (dbank1_lo_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU1) & ~lsu_tcu_ld_req_cancel_m2[1];
assign lsu1_rsp_vld_m2 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_vld_m2 & (dbank1_hi_rsp_id_m2[TCM_ID_W-1-:4] == EXT_ID_LSU1) & ~lsu_tcu_ld_req_cancel_m2[1];

//拓展位宽，从ITCM读取64-bit数据, 根据地址的低位addr[2]选择返回高32-bit还是低32-bit数据给LSU/VPU
assign lsu0_rsp_vld_m2 [MUX_LSU_ITCM_LO ] = ibank_rsp_vld_m2     & (ibank_rsp_id_m2    [TCM_ID_W-1-:4] == EXT_ID_LSU0) & ~ibank_rsp_addr_m2[2] & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu0_rsp_vld_m2 [MUX_LSU_ITCM_HI ] = ibank_rsp_vld_m2     & (ibank_rsp_id_m2    [TCM_ID_W-1-:4] == EXT_ID_LSU0) &  ibank_rsp_addr_m2[2] & ~lsu_tcu_ld_req_cancel_m2[0];
assign lsu1_rsp_vld_m2 [MUX_LSU_ITCM_LO ] = ibank_rsp_vld_m2     & (ibank_rsp_id_m2    [TCM_ID_W-1-:4] == EXT_ID_LSU1) & ~ibank_rsp_addr_m2[2] & ~lsu_tcu_ld_req_cancel_m2[1];
assign lsu1_rsp_vld_m2 [MUX_LSU_ITCM_HI ] = ibank_rsp_vld_m2     & (ibank_rsp_id_m2    [TCM_ID_W-1-:4] == EXT_ID_LSU1) &  ibank_rsp_addr_m2[2] & ~lsu_tcu_ld_req_cancel_m2[1];

assign lsu0_rsp_vld_m2 [MUX_LSU_VTCM    ] = (|vbank_lsu0_rsp_vld_m2_oh) & ~lsu_tcu_ld_req_cancel_m2[0]; //只要有任一 vbank 给出返回，且该 LSU0 的请求未取消，则在 VTCM 路径上标记响应有效。
assign lsu1_rsp_vld_m2 [MUX_LSU_VTCM    ] = (|vbank_lsu1_rsp_vld_m2_oh) & ~lsu_tcu_ld_req_cancel_m2[1]; //只要有任一 vbank 给出返回，且该 LSU1 的请求未取消，则在 VTCM 路径上标记响应有效。

assign lsu0_rsp_data_m2[MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_data_m2;      //DTCM0的低位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_data_m2;      //DTCM0的高位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_data_m2;      //DTCM1的低位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_data_m2;      //DTCM1的高位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_ITCM_LO ] = ibank_rsp_data_m2[31: 0];   //ITCM的低位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_ITCM_HI ] = ibank_rsp_data_m2[63:32];   //ITCM的高位返回数据给LSU0
assign lsu0_rsp_data_m2[MUX_LSU_VTCM    ] = vbank_lsu0_rsp_data_m2;     //VTCM的返回数据给LSU0
 
assign lsu1_rsp_data_m2[MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_data_m2;      //DTCM0的低位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_data_m2;      //DTCM0的高位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_data_m2;      //DTCM1的低位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_data_m2;      //DTCM1的高位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_ITCM_LO ] = ibank_rsp_data_m2[31: 0];   //ITCM的低位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_ITCM_HI ] = ibank_rsp_data_m2[63:32];   //ITCM的高位返回数据给LSU1
assign lsu1_rsp_data_m2[MUX_LSU_VTCM    ] = vbank_lsu1_rsp_data_m2;     //VTCM的返回数据给LSU1
 
assign lsu0_rsp_id_m2  [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM0的低位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM0的高位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM1的低位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM1的高位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_ITCM_LO ] = ibank_rsp_id_m2     [($clog2(6) + 1)-1:0]; //ITCM的低位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_ITCM_HI ] = ibank_rsp_id_m2     [($clog2(6) + 1)-1:0]; //ITCM的高位返回id给LSU0
assign lsu0_rsp_id_m2  [MUX_LSU_VTCM    ] = vbank_lsu0_rsp_id_m2[($clog2(6) + 1)-1:0]; //VTCM的返回id给LSU0

assign lsu1_rsp_id_m2  [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM0的低位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM0的高位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM1的低位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_id_m2 [($clog2(6) + 1)-1:0]; //DTCM1的高位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_ITCM_LO ] = ibank_rsp_id_m2     [($clog2(6) + 1)-1:0]; //ITCM的低位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_ITCM_HI ] = ibank_rsp_id_m2     [($clog2(6) + 1)-1:0]; //ITCM的高位返回id给LSU1
assign lsu1_rsp_id_m2  [MUX_LSU_VTCM    ] = vbank_lsu1_rsp_id_m2[($clog2(6) + 1)-1:0]; //VTCM的返回id给LSU1
 
assign tcu_lsu_ld_rsp_valid_m2[0] = |lsu0_rsp_vld_m2; //LSU0的返回有效
assign tcu_lsu_ld_rsp_valid_m2[1] = |lsu1_rsp_vld_m2; //LSU1的返回有效

//从ITCM读取64-bit数据, 根据地址的低位选择返回32-bit数据给LSU/VPU
wing_cbb_aomux #(.NUM(7), .WIDTH(32              )) u_aomux_lsu0_rsp_data (.data_arr(lsu0_rsp_data_m2), .sel_in_onehot0(lsu0_rsp_vld_m2), .data_sel(tcu_lsu_ld_rsp_data_m2 [0])); //LSU0的返回数据
wing_cbb_aomux #(.NUM(7), .WIDTH(($clog2(6) + 1))) u_aomux_lsu0_rsp_id_m2(.data_arr(lsu0_rsp_id_m2  ), .sel_in_onehot0(lsu0_rsp_vld_m2), .data_sel(tcu_lsu_ld_rsp_lsqid_m2[0])); //LSU0的返回id
wing_cbb_aomux #(.NUM(7), .WIDTH(32              )) u_aomux_lsu1_rsp_data (.data_arr(lsu1_rsp_data_m2), .sel_in_onehot0(lsu1_rsp_vld_m2), .data_sel(tcu_lsu_ld_rsp_data_m2 [1])); //LSU1的返回数据
wing_cbb_aomux #(.NUM(7), .WIDTH(($clog2(6) + 1))) u_aomux_lsu1_rsp_id_m2(.data_arr(lsu1_rsp_id_m2  ), .sel_in_onehot0(lsu1_rsp_vld_m2), .data_sel(tcu_lsu_ld_rsp_lsqid_m2[1])); //LSU1的返回id

//从ITCM_LO、ITCM_HI、DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、VTCM选出返回LSU0的vld信号
//只需要一个响应源就能满足M3阶段的需求，因为ITCM是单个RAM，所以只需要一个响应源
assign lsu0_rsp_vld_m3[MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU0); //DTCM0的低位返回LSU0的vld信号
assign lsu0_rsp_vld_m3[MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU0); //DTCM0的高位返回LSU0的vld信号
assign lsu0_rsp_vld_m3[MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU0); //DTCM1的低位返回LSU0的vld信号
assign lsu0_rsp_vld_m3[MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU0); //DTCM1的高位返回LSU0的vld信号
assign lsu0_rsp_vld_m3[MUX_LSU_ITCM_LO ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_LSU0); //ITCM的低位返回LSU0的vld信号
assign lsu0_rsp_vld_m3[MUX_LSU_ITCM_HI ] = 1'b0;   // Tie 0 since ITCM is a whole single RAM, and M3 only response id/err. So one single source from ITCM is enough.
assign lsu0_rsp_vld_m3[MUX_LSU_VTCM    ] = (|vbank_lsu0_rsp_vld_m3_oh); //VTCM的返回LSU0的vld信号

//从ITCM_LO、ITCM_HI、DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、VTCM选出返回LSU1的vld信号
//只需要一个响应源就能满足M3阶段的需求，因为ITCM是单个RAM，所以只需要一个响应源
assign lsu1_rsp_vld_m3[MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU1); //DTCM0的低位返回LSU1的vld信号
assign lsu1_rsp_vld_m3[MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU1); //DTCM0的高位返回LSU1的vld信号
assign lsu1_rsp_vld_m3[MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU1); //DTCM1的低位返回LSU1的vld信号
assign lsu1_rsp_vld_m3[MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_LSU1); //DTCM1的高位返回LSU1的vld信号
assign lsu1_rsp_vld_m3[MUX_LSU_ITCM_LO ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_LSU1);
assign lsu1_rsp_vld_m3[MUX_LSU_ITCM_HI ] = 1'b0; //ITCM的高位返回LSU1的vld信号
assign lsu1_rsp_vld_m3[MUX_LSU_VTCM    ] = (|vbank_lsu1_rsp_vld_m3_oh); //VTCM的返回LSU1的vld信号

//从ITCM_LO、ITCM_HI、DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、VTCM选出返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM0的低位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM0的高位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM1的低位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM1的高位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_id_m3     [($clog2(6) + 1)-1:0]; //ITCM的低位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_ITCM_HI ] = {($clog2(6) + 1){1'b0}}; //ITCM的高位返回LSU0的id
assign lsu0_rsp_id_m3 [MUX_LSU_VTCM    ] = vbank_lsu0_rsp_id_m3[($clog2(6) + 1)-1:0]; //VTCM的返回LSU0的id
 
//从ITCM_LO、ITCM_HI、DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、VTCM选出返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM0的低位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM0的高位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM1的低位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_id_m3 [($clog2(6) + 1)-1:0]; //DTCM1的高位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_id_m3     [($clog2(6) + 1)-1:0]; //ITCM的低位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_ITCM_HI ] = {($clog2(6) + 1){1'b0}}; //ITCM的高位返回LSU1的id
assign lsu1_rsp_id_m3 [MUX_LSU_VTCM    ] = vbank_lsu1_rsp_id_m3[($clog2(6) + 1)-1:0]; //VTCM的返回LSU1的id
 
assign tcu_lsu_ld_rsp_valid_m3[0] = |lsu0_rsp_vld_m3; //LSU0的返回有效
assign tcu_lsu_ld_rsp_valid_m3[1] = |lsu1_rsp_vld_m3; //LSU1的返回有效

//根据返回LSU0的vld信号，选出返回LSU0的id以及LSU1的id
wing_cbb_aomux #(.NUM(7), .WIDTH(($clog2(6) + 1))) u_aomux_lsu0_rsp_id_m3(.data_arr(lsu0_rsp_id_m3), .sel_in_onehot0(lsu0_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_lsqid_m3[0])); //返回LSU0的id
wing_cbb_aomux #(.NUM(7), .WIDTH(($clog2(6) + 1))) u_aomux_lsu1_rsp_id_m3(.data_arr(lsu1_rsp_id_m3), .sel_in_onehot0(lsu1_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_lsqid_m3[1])); //返回LSU1的id

assign lsu0_rsp_se_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_se_m3 & ~(dbank0_lo_rsp_de_m3); //当出现DTCM0 出现1bit错误，同时没有2 bit错误时有效
assign lsu0_rsp_se_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_se_m3 & ~(dbank0_hi_rsp_de_m3); //当出现DTCM0 出现1bit错误，同时没有2 bit错误时有效
assign lsu0_rsp_se_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_se_m3 & ~(dbank1_lo_rsp_de_m3); //当出现DTCM1 出现1bit错误，同时没有2 bit错误时有效
assign lsu0_rsp_se_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_se_m3 & ~(dbank1_hi_rsp_de_m3); //当出现DTCM1 出现1bit错误，同时没有2 bit错误时有效
assign lsu0_rsp_se_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_se_m3     & ~(ibank_rsp_de_m3);  //当出现ITCM 出现1bit错误，同时没有2 bit错误时有效
assign lsu0_rsp_se_m3 [MUX_LSU_ITCM_HI ] = 1'b0; //由于ITCM是一块独立的ram，所以只输出一组error
assign lsu0_rsp_se_m3 [MUX_LSU_VTCM    ] = vbank_lsu0_rsp_se_m3; //VTCM的返回LSU0的se信号

assign lsu1_rsp_se_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_se_m3 & ~(dbank0_lo_rsp_de_m3); //当出现DTCM0 出现1bit错误，同时没有2 bit错误时有效
assign lsu1_rsp_se_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_se_m3 & ~(dbank0_hi_rsp_de_m3);  //当出现DTCM0 出现1bit错误，同时没有2 bit错误时有效
assign lsu1_rsp_se_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_se_m3 & ~(dbank1_lo_rsp_de_m3); //当出现DTCM1 出现1bit错误，同时没有2 bit错误时有效
assign lsu1_rsp_se_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_se_m3 & ~(dbank1_hi_rsp_de_m3); //当出现DTCM1 出现1bit错误，同时没有2 bit错误时有效
assign lsu1_rsp_se_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_se_m3     & ~(ibank_rsp_de_m3);  //当出现ITCM 出现1bit错误，同时没有2 bit错误时有效
assign lsu1_rsp_se_m3 [MUX_LSU_ITCM_HI ] = vbank_lsu1_rsp_se_m3; //VTCM的返回LSU1的se信号
assign lsu1_rsp_se_m3 [MUX_LSU_VTCM    ] = vbank_lsu1_rsp_se_m3; //VTCM的返回LSU1的se信号
 
assign lsu0_rsp_de_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_de_m3; //DTCM0的返回LSU0的de信号
assign lsu0_rsp_de_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_de_m3;  //DTCM0的返回LSU0的de信号
assign lsu0_rsp_de_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_de_m3; //DTCM1的返回LSU0的de信号
assign lsu0_rsp_de_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_de_m3; //DTCM1的返回LSU0的de信号
assign lsu0_rsp_de_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_de_m3; //ITCM的返回LS
assign lsu0_rsp_de_m3 [MUX_LSU_ITCM_HI ] = 1'b0; //由于ITCM是一块独立的ram，所以只输出一组error
assign lsu0_rsp_de_m3 [MUX_LSU_VTCM    ] = vbank_lsu0_rsp_de_m3; //VTCM的返回LSU0的de信号
 
assign lsu1_rsp_de_m3 [MUX_LSU_DTCM0_LO] = dbank0_lo_rsp_de_m3; //DTCM0的返回LSU1的de信号
assign lsu1_rsp_de_m3 [MUX_LSU_DTCM0_HI] = dbank0_hi_rsp_de_m3;  //DTCM0的返回LSU1的de信号
assign lsu1_rsp_de_m3 [MUX_LSU_DTCM1_LO] = dbank1_lo_rsp_de_m3; //DTCM1的返回LSU1的de信号
assign lsu1_rsp_de_m3 [MUX_LSU_DTCM1_HI] = dbank1_hi_rsp_de_m3; //DTCM1的返回LSU1的de信号
assign lsu1_rsp_de_m3 [MUX_LSU_ITCM_LO ] = ibank_rsp_de_m3; //ITCM的返回LSU1的de信号
assign lsu1_rsp_de_m3 [MUX_LSU_ITCM_HI ] = 1'b0;//由于ITCM是一块独立的ram，所以只输出一组error
assign lsu1_rsp_de_m3 [MUX_LSU_VTCM    ] = vbank_lsu1_rsp_de_m3; //VTCM的返回LSU1的de信号

//根据返回LSU0的vld信号，选出返回LSU0的se信号以及LSU1的se信号
wing_cbb_aomux #(.NUM(7), .WIDTH(1)) u_aomux_lsu0_rsp_se_m3(.data_arr(lsu0_rsp_se_m3), .sel_in_onehot0(lsu0_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_replay_m3[0])); //根据vld信号，选出返回LSU0的se信号
wing_cbb_aomux #(.NUM(7), .WIDTH(1)) u_aomux_lsu1_rsp_se_m3(.data_arr(lsu1_rsp_se_m3), .sel_in_onehot0(lsu1_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_replay_m3[1])); //根据vld信号，选出返回LSU1的se信号

//根据返回LSU0的vld信号，选出返回LSU0的raserr信号以及LSU1的raserr信号
wing_cbb_aomux #(.NUM(7), .WIDTH(1)) u_aomux_lsu0_rsp_de_m3(.data_arr(lsu0_rsp_de_m3), .sel_in_onehot0(lsu0_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_raserr_m3[0])); //根据vld信号，选出返回LSU0的raserr信号
wing_cbb_aomux #(.NUM(7), .WIDTH(1)) u_aomux_lsu1_rsp_de_m3(.data_arr(lsu1_rsp_de_m3), .sel_in_onehot0(lsu1_rsp_vld_m3), .data_sel(tcu_lsu_ld_rsp_raserr_m3[1])); //根据vld信号，选出返回LSU1的raserr信号

//--------------------------------------------------------
// SBU resposne at M3 stage, with ecc correction.
// 4'b0010 - SBU
//--------------------------------------------------------
//从DTCM0、DTCM1、ITCM、VTCM选出返回SBU的vld信号
assign sbu_rsp_vld_m3[MUX_SBU_DTCM0] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU); //DTCM0的返回SBU的vld信号
assign sbu_rsp_vld_m3[MUX_SBU_DTCM1] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU); //DTCM1的返回SBU的vld信号
assign sbu_rsp_vld_m3[MUX_SBU_ITCM ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_SBU); //ITCM的返回SBU的vld信号
assign sbu_rsp_vld_m3[MUX_SBU_VTCM ] = |vbank_sbu_rsp_vld_m3_vec; //VTCM的返回SBU的vld信号

//从DTCM0、DTCM1、ITCM、VTCM选出返回SBU的id
assign sbu_rsp_id_m3[MUX_SBU_DTCM0] = dbank0_lo_rsp_id_m3[$clog2(6)-1:0]; //DTCM0的返回SBU的id
assign sbu_rsp_id_m3[MUX_SBU_DTCM1] = dbank1_lo_rsp_id_m3[$clog2(6)-1:0]; //DTCM1的返回SBU的id
assign sbu_rsp_id_m3[MUX_SBU_ITCM ] = ibank_rsp_id_m3    [$clog2(6)-1:0]; //ITCM的返回SBU的id
assign sbu_rsp_id_m3[MUX_SBU_VTCM ] = vbank_sbu_rsp_id_m3[$clog2(6)-1:0]; //VTCM的返回SBU的id

//从DTCM0、DTCM1、ITCM、VTCM选出返回SBU的de信号
assign sbu_rsp_de_m3[MUX_SBU_DTCM0] = dbank0_lo_rsp_de_m3 | dbank0_hi_rsp_de_m3; //DTCM0的返回SBU的de信号
assign sbu_rsp_de_m3[MUX_SBU_DTCM1] = dbank1_lo_rsp_de_m3 | dbank1_hi_rsp_de_m3; //DTCM1的返回SBU的de信号
assign sbu_rsp_de_m3[MUX_SBU_ITCM ] = ibank_rsp_de_m3    ; //ITCM的返回SBU的de信号
assign sbu_rsp_de_m3[MUX_SBU_VTCM ] = vbank_sbu_rsp_de_m3; //VTCM的返回SBU的de信号
 
//选出返回SBU的id
wing_cbb_aomux #(.NUM(4), .WIDTH($clog2(6))) u_aomux_sbu_rsp_id_m3(.data_arr(sbu_rsp_id_m3), .sel_in_onehot0(sbu_rsp_vld_m3), .data_sel(f));
//选出返回SBU的de信号
wing_cbb_aomux #(.NUM(4), .WIDTH(1))         u_aomux_sbu_rsp_de_m3(.data_arr(sbu_rsp_de_m3), .sel_in_onehot0(sbu_rsp_vld_m3), .data_sel(sbu_rsp_de_mux));

assign sbu_atop_bvld_m3[MUX_SBU_ATOP_DTCM0_LO] = (dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank0_lo_atop_b_infly_m3; //DTCM0的低位返回SBU的b_infly信号
assign sbu_atop_bvld_m3[MUX_SBU_ATOP_DTCM0_HI] = (dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank0_hi_atop_b_infly_m3; //DTCM0的高位返回SBU的b_infly信号
assign sbu_atop_bvld_m3[MUX_SBU_ATOP_DTCM1_LO] = (dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank1_lo_atop_b_infly_m3; //DTCM1的低位返回SBU的b_infly信号
assign sbu_atop_bvld_m3[MUX_SBU_ATOP_DTCM1_HI] = (dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank1_hi_atop_b_infly_m3; //DTCM1的高位返回SBU的b_infly信号

assign sbu_atop_rvld_m3 [MUX_SBU_ATOP_DTCM0_LO] = (dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank0_lo_atop_r_infly_m3; //DTCM0的低位返回SBU的r_infly信号
assign sbu_atop_rvld_m3 [MUX_SBU_ATOP_DTCM0_HI] = (dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank0_hi_atop_r_infly_m3; //DTCM0的高位返回SBU的r_infly信号
assign sbu_atop_rvld_m3 [MUX_SBU_ATOP_DTCM1_LO] = (dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank1_lo_atop_r_infly_m3; //DTCM1的低位返回SBU的r_infly信号
assign sbu_atop_rvld_m3 [MUX_SBU_ATOP_DTCM1_HI] = (dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SBU)) & dbank1_hi_atop_r_infly_m3; //DTCM1的高位返回SBU的r_infly信号

assign sbu_atop_rdata_m3[MUX_SBU_ATOP_DTCM0_LO] = dbank0_lo_rsp_data_m3; //DTCM0原子数据的低位返回SBU的rdata
assign sbu_atop_rdata_m3[MUX_SBU_ATOP_DTCM0_HI] = dbank0_hi_rsp_data_m3; //DTCM0原子数据的高位返回SBU的rdata
assign sbu_atop_rdata_m3[MUX_SBU_ATOP_DTCM1_LO] = dbank1_lo_rsp_data_m3; //DTCM1原子数据的低位返回SBU的rdata
assign sbu_atop_rdata_m3[MUX_SBU_ATOP_DTCM1_HI] = dbank1_hi_rsp_data_m3; //DTCM1原子数据的高位返回SBU的rdata

assign sbu_atop_id_m3[MUX_SBU_ATOP_DTCM0_LO]   = dbank0_lo_rsp_id_m3[$clog2(6)-1:0]; //DTCM0原子数据的低位返回SBU的id
assign sbu_atop_id_m3[MUX_SBU_ATOP_DTCM0_HI]   = dbank0_hi_rsp_id_m3[$clog2(6)-1:0]; //DTCM0原子数据的高位返回SBU的id
assign sbu_atop_id_m3[MUX_SBU_ATOP_DTCM1_LO]   = dbank1_lo_rsp_id_m3[$clog2(6)-1:0]; //DTCM1原子数据的低位返回SBU的id
assign sbu_atop_id_m3[MUX_SBU_ATOP_DTCM1_HI]   = dbank1_hi_rsp_id_m3[$clog2(6)-1:0]; //DTCM1原子数据的高位返回SBU的id
 
assign sbu_atop_de_m3[MUX_SBU_ATOP_DTCM0_LO]   = dbank0_lo_rsp_de_m3; //DTCM0原子数据的低位返回SBU的de信号
assign sbu_atop_de_m3[MUX_SBU_ATOP_DTCM0_HI]   = dbank0_hi_rsp_de_m3; //DTCM0原子数据的高位返回SBU的de信号
assign sbu_atop_de_m3[MUX_SBU_ATOP_DTCM1_LO]   = dbank1_lo_rsp_de_m3; //DTCM1原子数据的低位返回SBU的de信号
assign sbu_atop_de_m3[MUX_SBU_ATOP_DTCM1_HI]   = dbank1_hi_rsp_de_m3; //DTCM1原子数据的高位返回SBU的de信号
 
assign tcu_sbu_rsp_vld    = (|sbu_atop_bvld_m3) | (|sbu_rsp_vld_m3); //返回SBU的vld信号
assign tcu_sbu_rsp_id     = (|sbu_atop_bvld_m3) ? tcu_sbu_atop_rid : sbu_rsp_id_mux; //返回SBU的id
assign tcu_sbu_rsp_raserr = (|sbu_atop_bvld_m3) ? tcu_sbu_atop_raserr : sbu_rsp_de_mux; //返回SBU的两bit错误
 
//返回SBU的atop的r_infly信号
assign tcu_sbu_atop_rvld  = |sbu_atop_rvld_m3; //返回SBU的atop的有效返回信号

wing_cbb_aomux #(.NUM(4), .WIDTH(32                  )) u_aomux_sbu_atop_rdata_m3(.data_arr(sbu_atop_rdata_m3 ), .sel_in_onehot0(sbu_atop_rvld_m3), .data_sel(tcu_sbu_atop_rdata )); //根据rvld信号，选出返回SBU的atop的原子数据
wing_cbb_aomux #(.NUM(4), .WIDTH($clog2(6))) u_aomux_sbu_atop_id_m3   (.data_arr(sbu_atop_id_m3    ), .sel_in_onehot0(sbu_atop_bvld_m3), .data_sel(tcu_sbu_atop_rid   )); //根据bvld信号，选出返回SBU的atop的id
wing_cbb_aomux #(.NUM(4), .WIDTH(1                   )) u_aomux_sbu_atop_de_m3   (.data_arr(sbu_atop_de_m3    ), .sel_in_onehot0(sbu_atop_bvld_m3), .data_sel(tcu_sbu_atop_raserr)); //根据bvld信号，选出返回SBU的atop的两bit错误

//--------------------------------------------------------
// SLV-BUS resposne at M3 stage, with ecc correction.
// 4'b0011 - SLV-BUS
//--------------------------------------------------------
assign slv_rsp_vld_m3 [MUX_SLV_ITCM ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_SLV); //将m3纠正后的数据从ITCM返回给bmu的有效信号
assign slv_rsp_vld_m3 [MUX_SLV_DTCM0] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SLV); //将m3纠正后的数据从DTCM0返回给bmu的有效信号
assign slv_rsp_vld_m3 [MUX_SLV_DTCM1] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_SLV); //将m3纠正后的数据从DTCM1返回给bmu的有效信号
assign slv_rsp_vld_m3 [MUX_SLV_VTCM ] = |vbank_slv_rsp_vld_m3_vec; //将m3纠正后的数据从VTCM返回给bmu的有效信号

assign slv_rsp_data_m3[MUX_SLV_ITCM ] = ibank_rsp_data_m3; //将m3纠正后的数据返回给bmu
assign slv_rsp_data_m3[MUX_SLV_DTCM0] = {dbank0_hi_rsp_data_m3, dbank0_lo_rsp_data_m3}; //将m3纠正后的数据从DTCM0返回给bmu
assign slv_rsp_data_m3[MUX_SLV_DTCM1] = {dbank1_hi_rsp_data_m3, dbank1_lo_rsp_data_m3}; //将m3纠正后的数据从DTCM1返回给bmu
assign slv_rsp_data_m3[MUX_SLV_VTCM ] = vbank_slv_rsp_data_m3; //将m3纠正后的数据从VTCM返回给bmu
 
assign slv_rsp_id_m3  [MUX_SLV_ITCM ] = ibank_rsp_id_m3    [(8 + 2 + 3)-1:0]; //将m3纠正后的数据从ITCM返回给bmu的id
assign slv_rsp_id_m3  [MUX_SLV_DTCM0] = dbank0_lo_rsp_id_m3[(8 + 2 + 3)-1:0]; //将m3纠正后的数据从DTCM0返回给bmu的id
assign slv_rsp_id_m3  [MUX_SLV_DTCM1] = dbank1_lo_rsp_id_m3[(8 + 2 + 3)-1:0]; //将m3纠正后的数据从DTCM1返回给bmu的id
assign slv_rsp_id_m3  [MUX_SLV_VTCM ] = vbank_slv_rsp_id_m3[(8 + 2 + 3)-1:0]; //将m3纠正后的数据从VTCM返回给bmu的id
 
assign slv_rsp_de_m3  [MUX_SLV_ITCM ] = ibank_rsp_de_m3    ; //m3从ITCM返回给bmu的de信号
assign slv_rsp_de_m3  [MUX_SLV_DTCM0] = dbank0_lo_rsp_de_m3 | dbank0_hi_rsp_de_m3; //m3从DTCM0返回给bmu的de信号
assign slv_rsp_de_m3  [MUX_SLV_DTCM1] = dbank1_lo_rsp_de_m3 | dbank1_hi_rsp_de_m3; //m3从DTCM1返回给bmu的de信号
assign slv_rsp_de_m3  [MUX_SLV_VTCM ] = vbank_slv_rsp_de_m3; //m3从VTCM返回给bmu的de信号

//选出slv的rsp数据
wing_cbb_aomux #(.NUM(4), .WIDTH(64                     )) u_aomux_slv_rsp_data (.data_arr(slv_rsp_data_m3), .sel_in_onehot0(slv_rsp_vld_m3), .data_sel(bmu_rsp_data_pre  )); //选择出slv的rsp数据
//选出slv的rsp的id
wing_cbb_aomux #(.NUM(4), .WIDTH((8 + 2 + 3))) u_aomux_slv_rsp_id   (.data_arr(slv_rsp_id_m3  ), .sel_in_onehot0(slv_rsp_vld_m3), .data_sel(bmu_rsp_id_pre    )); //选择出slv的rsp的id
//选出slv的rsp的两bit错误
wing_cbb_aomux #(.NUM(4), .WIDTH(1                      )) u_aomux_slv_rsp_de_m3(.data_arr(slv_rsp_de_m3  ), .sel_in_onehot0(slv_rsp_vld_m3), .data_sel(bmu_rsp_raserr_pre)); //选择出slv的rsp的两bit错误

if (`CHUNJUN_MBUS_DATA_W == 128) begin: g_bmu_rsp_buffer //no use 
 
assign bmu_rsp_rcv_hi = bmu_rsp_rcv_lo_q & (|slv_rsp_vld_m3);  //no use
 
assign bmu_rsp_rcv_lo_set = bmu_req_buf_vld_q & (|slv_rsp_vld_m3);//no use
assign bmu_rsp_rcv_lo_clr = tcu_bmu_rsp_vld;//no use
assign bmu_rsp_rcv_lo_en  = bmu_rsp_rcv_lo_set | bmu_rsp_rcv_lo_clr;//no use
assign bmu_rsp_rcv_lo_d   = bmu_rsp_rcv_lo_set;//no use

`WDFFER(bmu_rsp_rcv_lo_q     , bmu_rsp_rcv_lo_d , bmu_rsp_rcv_lo_en, clk, rst_n)//no use
`WDFFER(bmu_rsp_rcv_data_lo  , bmu_rsp_data_pre , bmu_rsp_rcv_lo_set, clk, rst_n)//no use
`WDFFER(bmu_rsp_rcv_raserr_lo, bmu_rsp_raserr_pre, bmu_rsp_rcv_lo_set, clk, rst_n)//no use

assign tcu_bmu_rsp_vld    = bmu_rsp_rcv_hi;//no use
assign tcu_bmu_rsp_data   = {bmu_rsp_data_pre, bmu_rsp_rcv_data_lo};//no use
assign tcu_bmu_rsp_id     = bmu_rsp_id_pre;//no use
assign tcu_bmu_rsp_raserr = bmu_rsp_rcv_raserr_lo | bmu_rsp_raserr_pre;//no use

end else if (`CHUNJUN_MBUS_DATA_W == 64) begin: g_bmu_rsp_through
 
assign tcu_bmu_rsp_vld    = |slv_rsp_vld_m3;   //返回的给slv的使能信号
assign tcu_bmu_rsp_data   = bmu_rsp_data_pre;  //返回的给slv的数据
assign tcu_bmu_rsp_id     = bmu_rsp_id_pre;    //返回的给slv的id
assign tcu_bmu_rsp_raserr = bmu_rsp_raserr_pre;//返回的给slv的2bit error
 
end

//**********************************************************************************************//
`ifdef CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//
//--------------------------------------------------------
// VPU response at M3 stage, with ecc correction.
// 4'b1000 - VPU[0]
// 4'b1001 - VPU[1]
//--------------------------------------------------------

//从DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、ITCM_LO、ITCM_HI选出返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_DTCM0_LO] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU0); //DTCM0的低位返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_DTCM0_HI] = dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU0); //DTCM0的高位返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_DTCM1_LO] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU0); //DTCM1的低位返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_DTCM1_HI] = dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU0); //DTCM1的高位返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_ITCM_LO ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_VPU0) & ~ibank_rsp_addr_m3[2]; //ITCM的低位返回VPU0的vld信号
assign vpu0_rsp_vld_m3 [MUX_VPU_ITCM_HI ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_VPU0) &  ibank_rsp_addr_m3[2]; //ITCM的高位返回VPU0的vld信号

//从DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、ITCM_LO、ITCM_HI选出返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_DTCM0_LO] = dbank0_lo_rsp_vld_m3 & (dbank0_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU1); //DTCM0的低位返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_DTCM0_HI] = dbank0_hi_rsp_vld_m3 & (dbank0_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU1); //DTCM0的高位返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_DTCM1_LO] = dbank1_lo_rsp_vld_m3 & (dbank1_lo_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU1); //DTCM1的低位返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_DTCM1_HI] = dbank1_hi_rsp_vld_m3 & (dbank1_hi_rsp_id_m3[TCM_ID_W-1-:4] == EXT_ID_VPU1); //DTCM1的高位返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_ITCM_LO ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_VPU1) & ~ibank_rsp_addr_m3[2]; //ITCM的低位返回VPU1的vld信号
assign vpu1_rsp_vld_m3 [MUX_VPU_ITCM_HI ] = ibank_rsp_vld_m3     & (ibank_rsp_id_m3    [TCM_ID_W-1-:4] == EXT_ID_VPU1) &  ibank_rsp_addr_m3[2]; //ITCM的高位返回VPU1的vld信号

//从DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、ITCM_LO、ITCM_HI选出返回VPU0的数据
assign vpu_rsp_data_m3[MUX_VPU_DTCM0_LO] = dbank0_lo_rsp_data_m3;  //DTCM0的低位返回VPU0的数据
assign vpu_rsp_data_m3[MUX_VPU_DTCM0_HI] = dbank0_hi_rsp_data_m3;  //DTCM0的高位返回VPU1的数据
assign vpu_rsp_data_m3[MUX_VPU_DTCM1_LO] = dbank1_lo_rsp_data_m3;  //DTCM1的低位返回VPU0的数据
assign vpu_rsp_data_m3[MUX_VPU_DTCM1_HI] = dbank1_hi_rsp_data_m3;  //DTCM1的高位返回VPU1的数据
assign vpu_rsp_data_m3[MUX_VPU_ITCM_LO ] = ibank_rsp_data_m3[31: 0];  //ITCM的低位返回VPU0的数据
assign vpu_rsp_data_m3[MUX_VPU_ITCM_HI ] = ibank_rsp_data_m3[63:32]; //ITCM的高位返回VPU1的数据

//从DTCM0_LO、DTCM0_HI、DTCM1_LO、DTCM1_HI、ITCM_LO、ITCM_HI选出返回VPU0的id
assign vpu_rsp_id_m3  [MUX_VPU_DTCM0_LO] = dbank0_lo_rsp_id_m3[`CHUNJUN_VLQID_W-1:0]; //DTCM0的低位返回VPU0的id
assign vpu_rsp_id_m3  [MUX_VPU_DTCM0_HI] = dbank0_hi_rsp_id_m3[`CHUNJUN_VLQID_W-1:0]; //DTCM0的高位返回VPU1的id
assign vpu_rsp_id_m3  [MUX_VPU_DTCM1_LO] = dbank1_lo_rsp_id_m3[`CHUNJUN_VLQID_W-1:0]; //DTCM1的低位返回VPU0的id
assign vpu_rsp_id_m3  [MUX_VPU_DTCM1_HI] = dbank1_hi_rsp_id_m3[`CHUNJUN_VLQID_W-1:0]; //DTCM1的高位返回VPU1的id
assign vpu_rsp_id_m3  [MUX_VPU_ITCM_LO ] = ibank_rsp_id_m3    [`CHUNJUN_VLQID_W-1:0]; //ITCM的低位返回VPU0的id
assign vpu_rsp_id_m3  [MUX_VPU_ITCM_HI ] = ibank_rsp_id_m3    [`CHUNJUN_VLQID_W-1:0]; //ITCM的高位返回VPU1的id

// tcu -> vpu
assign tcu_vpu_ld_rsp_vld_m3[0] = |vpu0_rsp_vld_m3; //只要有响应vpu0的vld信号，则返回vpu0的vld信号有效
assign tcu_vpu_ld_rsp_vld_m3[1] = |vpu1_rsp_vld_m3; //只要有响应vpu1的vld信号，则返回vpu1的vld信号有效

wing_cbb_aomux #(.NUM(6), .WIDTH(32              )) u_aomux_vpu0_rsp_data (.data_arr(vpu_rsp_data_m3), .sel_in_onehot0(vpu0_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_data_m3 [0])); //返回VPU0的数据
wing_cbb_aomux #(.NUM(6), .WIDTH(`CHUNJUN_VLQID_W)) u_aomux_vpu0_rsp_id   (.data_arr(vpu_rsp_id_m3  ), .sel_in_onehot0(vpu0_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_vlqid_m3[0])); //返回VPU0的id
wing_cbb_aomux #(.NUM(6), .WIDTH(32              )) u_aomux_vpu1_rsp_data (.data_arr(vpu_rsp_data_m3), .sel_in_onehot0(vpu1_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_data_m3 [1])); //返回VPU1的数据
wing_cbb_aomux #(.NUM(6), .WIDTH(`CHUNJUN_VLQID_W)) u_aomux_vpu1_rsp_id   (.data_arr(vpu_rsp_id_m3  ), .sel_in_onehot0(vpu1_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_vlqid_m3[1])); //返回VPU1的id

assign vpu_rsp_de_m3 [MUX_VPU_DTCM0_LO] = dbank0_lo_rsp_de_m3; //DTCM0的低位返回VPU0的de信号
assign vpu_rsp_de_m3 [MUX_VPU_DTCM0_HI] = dbank0_hi_rsp_de_m3; //DTCM0的高位返回VPU1的de信号
assign vpu_rsp_de_m3 [MUX_VPU_DTCM1_LO] = dbank1_lo_rsp_de_m3; //DTCM1的低位返回VPU0的de信号
assign vpu_rsp_de_m3 [MUX_VPU_DTCM1_HI] = dbank1_hi_rsp_de_m3; //DTCM1的高位返回VPU1的de信号
assign vpu_rsp_de_m3 [MUX_VPU_ITCM_LO ] = ibank_rsp_de_m3;    //ITCM的低位返回VPU0的de信号
assign vpu_rsp_de_m3 [MUX_VPU_ITCM_HI ] = ibank_rsp_de_m3;    //ITCM的高位返回VPU1的de信号

wing_cbb_aomux #(.NUM(6), .WIDTH(1)) u_aomux_vpu0_rsp_de_m3(.data_arr(vpu_rsp_de_m3), .sel_in_onehot0(vpu0_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_raserr_m3[0]));//返回VPU0的de信号
wing_cbb_aomux #(.NUM(6), .WIDTH(1)) u_aomux_vpu1_rsp_de_m3(.data_arr(vpu_rsp_de_m3), .sel_in_onehot0(vpu1_rsp_vld_m3), .data_sel(tcu_vpu_ld_rsp_raserr_m3[1]));//返回VPU1的de信号

// vtcm -> vpu
for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_vpu_rsp
  assign vtcu_vpu_rsp_vld_m3[i]    = vbank_rsp_vld_m3[i] & (vbank_rsp_id_m3[i][TCM_ID_W-1-:4] == EXT_ID_VTCM); //vtcm的返回给NVPU的vld信号
  assign vtcu_vpu_rsp_data_m3[i]   = vbank_rsp_data_m3[i]; //vtcm的返回给NVPU的数据
  assign vtcu_vpu_rsp_info_m3[i]   = vbank_rsp_id_m3[i][`CHUNJUN_VLQID_W:0]; //vtcm的返回给NVPU的id
  assign vtcu_vpu_rsp_raserr_m3[i] = vbank_rsp_de_m3[i]; //vtcm的返回给NVPU的de信号
end
//**********************************************************************************************//
`endif //CHUNJUN_SUPPORT_V_EXT
//**********************************************************************************************//

//=================================================================================
// RAS Interface - 可靠性、可用性和可服务性接口
//=================================================================================
// 功能：从各TCM bank收集ECC错误信息，聚合后上报给系统级RAS控制器
// 流程：1. 从bank获取se/de错误信号 2. 按优先级选择一路错误 3. 生成标准RAS字段

//=================================================================================
// ITCM 请求源类型识别
//=================================================================================
// 根据响应ID的高4位识别请求来源，用于生成RAS报告中的触发类型(tt)和访问错误类别(aec)
assign itcm_req_src_ras[RAS_SRC_LD    ]  = (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_LSU0) | (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_LSU1) | // 加载操作：LSU0/1
                                           (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_VPU0) | (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_VPU1) ; // 加载操作：LSU0/1, VPU0/1
assign itcm_req_src_ras[RAS_SRC_ST    ]  = (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_SBU); // 存储操作：SBU
assign itcm_req_src_ras[RAS_SRC_SLV_LD]  = (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_SLV) & ~ibank_rsp_wr_ras; // Slave总线读操作
assign itcm_req_src_ras[RAS_SRC_SLV_ST]  = (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_SLV) &  ibank_rsp_wr_ras; // Slave总线写操作
assign itcm_req_src_ras[RAS_SRC_IF    ]  = (ibank_rsp_id_ras[TCM_ID_W-1-:4] == EXT_ID_ICU); // 取指操作：ICU
 
//=================================================================================
// DTCM0 错误聚合和优先级选择
//=================================================================================
// DTCM0包含lo和hi两个32位bank，需要聚合两个bank的错误信号并按优先级选择

// 构造se/de错误向量：将两个bank的错误信号拼接，并用vld信号门控
assign dtcm0_rsp_se_ras_vec = {dbank0_hi_rsp_vld_ras & dbank0_hi_rsp_se_ras, dbank0_lo_rsp_vld_ras & dbank0_lo_rsp_se_ras }; // 拼出 se 向量（带 vld 门控）
assign dtcm0_rsp_de_ras_vec = {dbank0_hi_rsp_vld_ras & dbank0_hi_rsp_de_ras, dbank0_lo_rsp_vld_ras & dbank0_lo_rsp_de_ras }; // 拼出 de 向量（带 vld 门控）

// 优先级仲裁：使用优先队列为se和de分别生成onehot选择信号
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_dtcm0_se (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(dtcm0_rsp_se_ras_vec), .onehot_o(dtcm0_rsp_se_oh)); // 优先器：生成 onehot（se）
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_dtcm0_de (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(dtcm0_rsp_de_ras_vec), .onehot_o(dtcm0_rsp_de_oh)); // 优先器：生成 onehot（de）

// 最终选择：de错误优先级高于se错误（de不可纠正，se可纠正）
assign dtcm0_rsp_ras_oh = (|dtcm0_rsp_de_ras_vec) ? dtcm0_rsp_de_oh : dtcm0_rsp_se_oh; // de 优先于 se

// 根据选择信号复用出对应的ID、写标志和地址
wing_cbb_aomux #(.NUM(2), .WIDTH(TCM_ID_W)) u_aomux_dtcm0_id_ras   (.data_arr({dbank0_hi_rsp_id_ras  , dbank0_lo_rsp_id_ras  }), .sel_in_onehot0(dtcm0_rsp_ras_oh), .data_sel(dtcm0_ras_id)); // 选择 id
wing_cbb_aomux #(.NUM(2), .WIDTH(1       )) u_aomux_dtcm0_wr_ras   (.data_arr({dbank0_hi_rsp_wr_ras  , dbank0_lo_rsp_wr_ras  }), .sel_in_onehot0(dtcm0_rsp_ras_oh), .data_sel(dtcm0_ras_wr)); // 选择写标志
wing_cbb_aomux #(.NUM(2), .WIDTH(20      )) u_aomux_dtcm0_addr_ras (.data_arr({dbank0_hi_rsp_addr_ras, dbank0_lo_rsp_addr_ras}), .sel_in_onehot0(dtcm0_rsp_ras_oh), .data_sel(dtcm0_ras_addr_offs)); // 选择地址偏移

// DTCM0 请求源类型识别（与ITCM逻辑相同）
assign dtcm0_req_src_ras[RAS_SRC_LD    ] = (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU0) | (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU1) | 
                                           (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_VPU0) | (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_VPU1) ; // 加载操作
assign dtcm0_req_src_ras[RAS_SRC_ST    ] = (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_SBU) | (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_SBU) ; // 存储操作
assign dtcm0_req_src_ras[RAS_SRC_SLV_LD] = (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) & ~dtcm0_ras_wr; // Slave总线读操作
assign dtcm0_req_src_ras[RAS_SRC_SLV_ST] = (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) &  dtcm0_ras_wr; // Slave总线写操作
assign dtcm0_req_src_ras[RAS_SRC_IF    ] = (dtcm0_ras_id[TCM_ID_W-1-:4] == EXT_ID_ICU); // 取指操作

//=================================================================================
// DTCM1 错误聚合和优先级选择（可选）
//=================================================================================
// DTCM1的逻辑与DTCM0完全相同，但仅在CHUNJUN_SUPPORT_DTCM1宏定义时生效

// 构造se/de错误向量：将两个bank的错误信号拼接，并用vld信号门控
assign dtcm1_rsp_se_ras_vec = {dbank1_hi_rsp_vld_ras & dbank1_hi_rsp_se_ras, dbank1_lo_rsp_vld_ras & dbank1_lo_rsp_se_ras }; // 拼出 se 向量（带 vld 门控）
assign dtcm1_rsp_de_ras_vec = {dbank1_hi_rsp_vld_ras & dbank1_hi_rsp_de_ras, dbank1_lo_rsp_vld_ras & dbank1_lo_rsp_de_ras }; // 拼出 de 向量（带 vld 门控）

// 优先级仲裁：使用优先队列为se和de分别生成onehot选择信号
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_dtcm1_se (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(dtcm1_rsp_se_ras_vec), .onehot_o(dtcm1_rsp_se_oh)); // 优先器：生成 onehot（se）
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_dtcm1_de (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(dtcm1_rsp_de_ras_vec), .onehot_o(dtcm1_rsp_de_oh)); // 优先器：生成 onehot（de）

// 最终选择：de错误优先级高于se错误（de不可纠正，se可纠正）
assign dtcm1_rsp_ras_oh = (|dtcm1_rsp_de_ras_vec) ? dtcm1_rsp_de_oh : dtcm1_rsp_se_oh; // de 优先于 se

// 根据选择信号复用出对应的ID、写标志和地址
wing_cbb_aomux #(.NUM(2), .WIDTH(TCM_ID_W)) u_aomux_dtcm1_id_ras   (.data_arr({dbank1_hi_rsp_id_ras  , dbank1_lo_rsp_id_ras  }), .sel_in_onehot0(dtcm1_rsp_ras_oh), .data_sel(dtcm1_ras_id)); // 选择 id
wing_cbb_aomux #(.NUM(2), .WIDTH(1       )) u_aomux_dtcm1_wr_ras   (.data_arr({dbank1_hi_rsp_wr_ras  , dbank1_lo_rsp_wr_ras  }), .sel_in_onehot0(dtcm1_rsp_ras_oh), .data_sel(dtcm1_ras_wr)); // 选择写标志
wing_cbb_aomux #(.NUM(2), .WIDTH(20      )) u_aomux_dtcm1_addr_ras (.data_arr({dbank1_hi_rsp_addr_ras, dbank1_lo_rsp_addr_ras}), .sel_in_onehot0(dtcm1_rsp_ras_oh), .data_sel(dtcm1_ras_addr_offs)); // 选择地址偏移

// DTCM1 请求源类型识别（与DTCM0逻辑相同）
assign dtcm1_req_src_ras[RAS_SRC_LD    ] = (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU0) | (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU1) | 
                                           (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_VPU0) | (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_VPU1) ; // 加载操作
assign dtcm1_req_src_ras[RAS_SRC_ST    ] = (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_SBU) | (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_SBU) ; // 存储操作
assign dtcm1_req_src_ras[RAS_SRC_SLV_LD] = (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) & ~dtcm1_ras_wr; // Slave总线读操作
assign dtcm1_req_src_ras[RAS_SRC_SLV_ST] = (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) &  dtcm1_ras_wr; // Slave总线写操作
assign dtcm1_req_src_ras[RAS_SRC_IF    ] = (dtcm1_ras_id[TCM_ID_W-1-:4] == EXT_ID_ICU); // 取指操作

//=================================================================================
// VTCM 错误聚合和优先级选择（可选）
//=================================================================================
// VTCM包含多个32位bank，需要聚合所有bank的错误信号并按优先级选择

`ifdef CHUNJUN_SUPPORT_V_EXT
// 构造每个bank的se/de错误向量：用vld信号门控
for (genvar i=0; i<`CHUNJUN_VTCM_BANK_N; i++) begin: g_vtcm_rsp_ras_vec

  assign vbank_rsp_se_vec[i] = vbank_rsp_vld_ras[i] & vbank_rsp_se_ras[i]; // bank i的se错误（带vld门控）
  assign vbank_rsp_de_vec[i] = vbank_rsp_vld_ras[i] & vbank_rsp_de_ras[i]; // bank i的de错误（带vld门控）
 
end

// 优先级仲裁：使用优先队列为se和de分别生成onehot选择信号（多bank版本）
wing_cbb_priority_queue #(.MODE(0), .WIDTH(`CHUNJUN_VTCM_BANK_N), .LOCK(0)) u_ff1_vtcm_se (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(vbank_rsp_se_vec), .onehot_o(vbank_rsp_se_oh)); // 多 bank：se onehot
wing_cbb_priority_queue #(.MODE(0), .WIDTH(`CHUNJUN_VTCM_BANK_N), .LOCK(0)) u_ff1_vtcm_de (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(vbank_rsp_de_vec), .onehot_o(vbank_rsp_de_oh)); // 多 bank：de onehot

// 最终选择：de错误优先级高于se错误（de不可纠正，se可纠正）
assign vtcm_rsp_ras_oh = (|vbank_rsp_de_vec) ? vbank_rsp_de_oh : vbank_rsp_se_oh; // de 优先选择 bank

// 根据选择信号复用出对应的ID、写标志和地址（多bank版本）
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(TCM_ID_W)) u_aomux_vtcm_id_ras   (.data_arr(vbank_rsp_id_ras  ), .sel_in_onehot0(vtcm_rsp_ras_oh), .data_sel(vtcm_ras_id       )); // 选择 id
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(1       )) u_aomux_vtcm_wr_ras   (.data_arr(vbank_rsp_wr_ras  ), .sel_in_onehot0(vtcm_rsp_ras_oh), .data_sel(vtcm_ras_wr       )); // 选择写标志
wing_cbb_aomux #(.NUM(`CHUNJUN_VTCM_BANK_N), .WIDTH(20      )) u_aomux_vtcm_addr_ras (.data_arr(vbank_rsp_addr_ras), .sel_in_onehot0(vtcm_rsp_ras_oh), .data_sel(vtcm_ras_addr_offs)); // 选择地址偏移

// VTCM 请求源类型识别（支持VTCM专用ID）
assign vtcm_req_src_ras[RAS_SRC_LD    ]  = (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU0)                | // LSU0加载
                                           (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_LSU1)                | // LSU1加载
                                           (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_VTCM) & ~vtcm_ras_wr ; // VTCM读操作
assign vtcm_req_src_ras[RAS_SRC_ST    ]  = (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_SBU)                 | // SBU存储
                                           (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_VTCM) &  vtcm_ras_wr ; // VTCM写操作
assign vtcm_req_src_ras[RAS_SRC_SLV_LD]  = (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) & ~vtcm_ras_wr; // Slave总线读操作
assign vtcm_req_src_ras[RAS_SRC_SLV_ST]  = (vtcm_ras_id[TCM_ID_W-1-:4] == EXT_ID_SLV) &  vtcm_ras_wr; // Slave总线写操作

`endif // CHUNJUN_SUPPORT_V_EXT
 
//=================================================================================
// ITCM RAS 字段生成
//=================================================================================
// 根据ITCM bank的错误信息和请求源类型，生成标准RAS报告字段

// 基本错误状态字段
assign tcu_ras_valid   [RAS_ITCM ] = ibank_rsp_vld_ras & (ibank_rsp_se_ras | ibank_rsp_de_ras); // 有效：有响应且有错误
assign tcu_ras_ce      [RAS_ITCM ] = ibank_rsp_se_ras; // 可纠正错误：单比特错误
assign tcu_ras_ued     [RAS_ITCM ] = 1'b0; // 未定义错误：ITCM不支持，固定为0
assign tcu_ras_uec     [RAS_ITCM ] = ibank_rsp_de_ras; // 不可纠正错误：双比特错误
assign tcu_ras_priority[RAS_ITCM ] = 2'b0; // 优先级：ITCM优先级最低

// 触发类型：根据请求源类型编码（Load=4, Store=5, Slave_Load=6, Slave_Store=7, IF=4）
assign tcu_ras_tt      [RAS_ITCM ] = {4{itcm_req_src_ras[RAS_SRC_LD]    }} & 3'd4 | // 加载操作
                                     {4{itcm_req_src_ras[RAS_SRC_ST]    }} & 3'd5 | // 存储操作
                                     {4{itcm_req_src_ras[RAS_SRC_SLV_LD]}} & 3'd6 | // Slave读操作
                                     {4{itcm_req_src_ras[RAS_SRC_SLV_ST]}} & 3'd7 | // Slave写操作
                                     {4{itcm_req_src_ras[RAS_SRC_IF]    }} & 3'd4 ; // 取指操作

// 刷洗建议：de错误时不建议刷洗（可能破坏数据），se错误时建议刷洗
assign tcu_ras_scrub   [RAS_ITCM ] = ibank_rsp_de_ras ? 1'b0  : 1'b1; // de错误不刷洗，se错误刷洗
assign tcu_ras_ec      [RAS_ITCM ] = 8'd64; // 错误代码宽度：64位
assign tcu_ras_addr    [RAS_ITCM ] = {itcm_global_base_addr, ibank_rsp_addr_ras}; // 完整地址：基址+偏移

// 访问错误类别：根据请求源类型编码（LSU=1, Slave=3, ICU=0）
assign tcu_ras_aec     [RAS_ITCM ] = {4{itcm_req_src_ras[RAS_SRC_LD]    }} & 4'd1 | // LSU访问
                                     {4{itcm_req_src_ras[RAS_SRC_ST]    }} & 4'd1 | // LSU访问
                                     {4{itcm_req_src_ras[RAS_SRC_SLV_LD]}} & 4'd3 | // Slave访问
                                     {4{itcm_req_src_ras[RAS_SRC_SLV_ST]}} & 4'd3 | // Slave访问
                                     {4{itcm_req_src_ras[RAS_SRC_IF]    }} & 4'd0 ; // ICU访问

// 缓存相关字段（ITCM不支持缓存，固定为0）
assign tcu_ras_tag     [RAS_ITCM ] = 1'b0; // 标签位
assign tcu_ras_way     [RAS_ITCM ] = 4'b0; // 路选择
 
//=================================================================================
// DTCM0 RAS 字段生成
//=================================================================================
// 根据DTCM0 lo/hi bank的错误信息和请求源类型，生成标准RAS报告字段

// 基本错误状态字段：聚合lo和hi bank的错误信号
assign tcu_ras_valid   [RAS_DTCM0] = dbank0_lo_rsp_vld_ras & (dbank0_lo_rsp_se_ras | dbank0_lo_rsp_de_ras) | // lo bank有错误
                                     dbank0_hi_rsp_vld_ras & (dbank0_hi_rsp_se_ras | dbank0_hi_rsp_de_ras) ; // hi bank有错误
assign tcu_ras_ce      [RAS_DTCM0] = dbank0_lo_rsp_vld_ras & dbank0_lo_rsp_se_ras | // lo bank可纠正错误
                                     dbank0_hi_rsp_vld_ras & dbank0_hi_rsp_se_ras ; // hi bank可纠正错误
assign tcu_ras_ued     [RAS_DTCM0] = 1'b0; // 未定义错误：DTCM0不支持，固定为0
assign tcu_ras_uec     [RAS_DTCM0] = dbank0_lo_rsp_vld_ras & dbank0_lo_rsp_de_ras | // lo bank不可纠正错误
                                     dbank0_hi_rsp_vld_ras & dbank0_hi_rsp_de_ras ; // hi bank不可纠正错误
assign tcu_ras_priority[RAS_DTCM0] = 2'd3; // 优先级：DTCM0优先级为3

// 触发类型：根据请求源类型编码（与ITCM相同）
assign tcu_ras_tt      [RAS_DTCM0] = {4{dtcm0_req_src_ras[RAS_SRC_LD]    }} & 3'd4 | // 加载操作
                                     {4{dtcm0_req_src_ras[RAS_SRC_ST]    }} & 3'd5 | // 存储操作
                                     {4{dtcm0_req_src_ras[RAS_SRC_SLV_LD]}} & 3'd6 | // Slave读操作
                                     {4{dtcm0_req_src_ras[RAS_SRC_SLV_ST]}} & 3'd7 | // Slave写操作
                                     {4{dtcm0_req_src_ras[RAS_SRC_IF]    }} & 3'd4 ; // 取指操作

// 刷洗建议：de错误时不建议刷洗，se错误时建议刷洗
assign tcu_ras_scrub   [RAS_DTCM0] = tcu_ras_uec[RAS_DTCM0] ? 1'b0  : 1'b1; // de错误不刷洗，se错误刷洗
assign tcu_ras_ec      [RAS_DTCM0] = 8'd64; // 错误代码宽度：64位
assign tcu_ras_addr    [RAS_DTCM0] = {dtcm0_global_base_addr, dtcm0_ras_addr_offs}; // 完整地址：基址+偏移

// 访问错误类别：根据请求源类型编码（与ITCM相同）
assign tcu_ras_aec     [RAS_DTCM0] = {4{dtcm0_req_src_ras[RAS_SRC_LD]    }} & 4'd1 | // LSU访问
                                     {4{dtcm0_req_src_ras[RAS_SRC_ST]    }} & 4'd1 | // LSU访问
                                     {4{dtcm0_req_src_ras[RAS_SRC_SLV_LD]}} & 4'd3 | // Slave访问
                                     {4{dtcm0_req_src_ras[RAS_SRC_SLV_ST]}} & 4'd3 | // Slave访问
                                     {4{dtcm0_req_src_ras[RAS_SRC_IF]    }} & 4'd0 ; // ICU访问

// 缓存相关字段（DTCM0不支持缓存，固定为0）
assign tcu_ras_tag     [RAS_DTCM0] = 1'b0; // 标签位
assign tcu_ras_way     [RAS_DTCM0] = 4'b0; // 路选择

//=================================================================================
// DTCM1 RAS 字段生成（可选）
//=================================================================================
// DTCM1的RAS字段生成逻辑与DTCM0完全相同，但仅在CHUNJUN_SUPPORT_DTCM1宏定义时生效

`ifdef CHUNJUN_SUPPORT_DTCM1
// 基本错误状态字段：聚合lo和hi bank的错误信号（与DTCM0相同）
assign tcu_ras_valid   [RAS_DTCM1] = dbank1_lo_rsp_vld_ras & (dbank1_lo_rsp_se_ras | dbank1_lo_rsp_de_ras) | // lo bank有错误
                                     dbank1_hi_rsp_vld_ras & (dbank1_hi_rsp_se_ras | dbank1_hi_rsp_de_ras) ; // hi bank有错误
assign tcu_ras_ce      [RAS_DTCM1] = dbank1_lo_rsp_vld_ras & dbank1_lo_rsp_se_ras | // lo bank可纠正错误
                                     dbank1_hi_rsp_vld_ras & dbank1_hi_rsp_se_ras ; // hi bank可纠正错误
assign tcu_ras_ued     [RAS_DTCM1] = 1'b0; // 未定义错误：DTCM1不支持，固定为0
assign tcu_ras_uec     [RAS_DTCM1] = dbank1_lo_rsp_vld_ras & dbank1_lo_rsp_de_ras | // lo bank不可纠正错误
                                     dbank1_hi_rsp_vld_ras & dbank1_hi_rsp_de_ras ; // hi bank不可纠正错误                            
assign tcu_ras_priority[RAS_DTCM1] = 2'd3; // 优先级：DTCM1优先级为3

// 触发类型：根据请求源类型编码（与DTCM0相同）
assign tcu_ras_tt      [RAS_DTCM1] = {4{dtcm1_req_src_ras[RAS_SRC_LD]    }} & 3'd4 | // 加载操作
                                     {4{dtcm1_req_src_ras[RAS_SRC_ST]    }} & 3'd5 | // 存储操作
                                     {4{dtcm1_req_src_ras[RAS_SRC_SLV_LD]}} & 3'd6 | // Slave读操作
                                     {4{dtcm1_req_src_ras[RAS_SRC_SLV_ST]}} & 3'd7 | // Slave写操作
                                     {4{dtcm1_req_src_ras[RAS_SRC_IF]    }} & 3'd4 ; // 取指操作

// 刷洗建议：de错误时不建议刷洗，se错误时建议刷洗
assign tcu_ras_scrub   [RAS_DTCM1] = tcu_ras_uec[RAS_DTCM1] ? 1'b0  : 1'b1; // de错误不刷洗，se错误刷洗
assign tcu_ras_ec      [RAS_DTCM1] = 8'd64; // 错误代码宽度：64位
assign tcu_ras_addr    [RAS_DTCM1] = {dtcm1_global_base_addr, dtcm1_ras_addr_offs}; // 完整地址：基址+偏移

// 访问错误类别：根据请求源类型编码（与DTCM0相同）
assign tcu_ras_aec     [RAS_DTCM1] = {4{dtcm1_req_src_ras[RAS_SRC_LD]    }} & 4'd1 | // LSU访问
                                     {4{dtcm1_req_src_ras[RAS_SRC_ST]    }} & 4'd1 | // LSU访问
                                     {4{dtcm1_req_src_ras[RAS_SRC_SLV_LD]}} & 4'd3 | // Slave访问
                                     {4{dtcm1_req_src_ras[RAS_SRC_SLV_ST]}} & 4'd3 | // Slave访问
                                     {4{dtcm1_req_src_ras[RAS_SRC_IF]    }} & 4'd0 ; // ICU访问

// 缓存相关字段（DTCM1不支持缓存，固定为0）
assign tcu_ras_tag     [RAS_DTCM1] = 1'b0; // 标签位
assign tcu_ras_way     [RAS_DTCM1] = 4'b0; // 路选择
`else // CHUNJUN_SUPPORT_DTCM1
assign tcu_ras_valid   [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_ce      [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_ued     [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_uec     [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_priority[RAS_DTCM1] = 2'b0; //nouse
assign tcu_ras_tt      [RAS_DTCM1] = 3'b0; //nouse
assign tcu_ras_scrub   [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_ec      [RAS_DTCM1] = 8'b0; //nouse
assign tcu_ras_addr    [RAS_DTCM1] = 32'b0; //nouse 
assign tcu_ras_aec     [RAS_DTCM1] = 4'b0; //nouse
assign tcu_ras_tag     [RAS_DTCM1] = 1'b0; //nouse
assign tcu_ras_way     [RAS_DTCM1] = 4'b0; //nouse
`endif // CHUNJUN_SUPPORT_DTCM1

//=================================================================================
// VTCM RAS 字段生成（可选）
//=================================================================================
// 根据VTCM多bank的错误信息和请求源类型，生成标准RAS报告字段

`ifdef CHUNJUN_SUPPORT_V_EXT
// 基本错误状态字段：聚合所有bank的错误信号
assign tcu_ras_valid   [RAS_VTCM ] = (|vbank_rsp_se_vec) | (|vbank_rsp_de_vec); // 有效：任一bank有错误
assign tcu_ras_ce      [RAS_VTCM ] = (|vbank_rsp_se_vec); // 可纠正错误：任一bank有se错误
assign tcu_ras_ued     [RAS_VTCM ] = 1'b0; // 未定义错误：VTCM不支持，固定为0
assign tcu_ras_uec     [RAS_VTCM ] = (|vbank_rsp_de_vec); // 不可纠正错误：任一bank有de错误
assign tcu_ras_priority[RAS_VTCM ] = 2'd1; // 优先级：VTCM优先级为1（最高）

// 触发类型：根据请求源类型编码（不支持IF操作）
assign tcu_ras_tt      [RAS_VTCM ] = {4{vtcm_req_src_ras[RAS_SRC_LD]    }} & 3'd4 | // 加载操作
                                     {4{vtcm_req_src_ras[RAS_SRC_ST]    }} & 3'd5 | // 存储操作
                                     {4{vtcm_req_src_ras[RAS_SRC_SLV_LD]}} & 3'd6 | // Slave读操作
                                     {4{vtcm_req_src_ras[RAS_SRC_SLV_ST]}} & 3'd7 ; // Slave写操作

// 刷洗建议：de错误时不建议刷洗，se错误时建议刷洗
assign tcu_ras_scrub   [RAS_VTCM ] = tcu_ras_uec[RAS_VTCM] ? 1'b0  : 1'b1; // de错误不刷洗，se错误刷洗      
assign tcu_ras_ec      [RAS_VTCM ] = 8'd64; // 错误代码宽度：64位
assign tcu_ras_addr    [RAS_VTCM ] = {vtcm_global_base_addr, vtcm_ras_addr_offs}; // 完整地址：基址+偏移

// 访问错误类别：根据请求源类型编码（不支持IF操作）
assign tcu_ras_aec     [RAS_VTCM ] = {4{vtcm_req_src_ras[RAS_SRC_LD]    }} & 4'd1 | // LSU访问
                                     {4{vtcm_req_src_ras[RAS_SRC_ST]    }} & 4'd1 | // LSU访问
                                     {4{vtcm_req_src_ras[RAS_SRC_SLV_LD]}} & 4'd3 | // Slave访问
                                     {4{vtcm_req_src_ras[RAS_SRC_SLV_ST]}} & 4'd3 ; // Slave访问

// 缓存相关字段（VTCM不支持缓存，固定为0）
assign tcu_ras_tag     [RAS_VTCM ] = 1'b0; // 标签位
assign tcu_ras_way     [RAS_VTCM ] = 4'b0; // 路选择
`else // CHUNJUN_SUPPORT_V_EXT
assign tcu_ras_valid   [RAS_VTCM ] = 1'b0; //nouse                         
assign tcu_ras_ce      [RAS_VTCM ] = 1'b0; //nouse
assign tcu_ras_ued     [RAS_VTCM ] = 1'b0; //nouse
assign tcu_ras_uec     [RAS_VTCM ] = 1'b0; //nouse
assign tcu_ras_priority[RAS_VTCM ] = 2'b0; //nouse
assign tcu_ras_tt      [RAS_VTCM ] = 3'b0; //nouse
assign tcu_ras_scrub   [RAS_VTCM ] = 1'b0; //nouse
assign tcu_ras_ec      [RAS_VTCM ] = 8'b0; //nouse
assign tcu_ras_addr    [RAS_VTCM ] = 32'b0;//nouse 
assign tcu_ras_aec     [RAS_VTCM ] = 4'b0; //nouse   
assign tcu_ras_tag     [RAS_VTCM ] = 1'b0; //nouse
assign tcu_ras_way     [RAS_VTCM ] = 4'b0; //nouse
`endif // CHUNJUN_SUPPORT_V_EXT

//=================================================================================
// TCU 空闲状态指示
//=================================================================================
// 功能：指示整个TCU是否处于空闲状态，用于系统级电源管理和调试
// 条件：所有TCM bank都处于空闲状态时，TCU才被认为是空闲的

assign tcu_idle = ibank_idle & (dbank0_lo_idle & dbank0_hi_idle) // ITCM和DTCM0的所有bank都空闲
`ifdef CHUNJUN_SUPPORT_DTCM1
                & (dbank1_lo_idle & dbank1_hi_idle) // DTCM1的所有bank都空闲（可选）
`endif // CHUNJUN_SUPPORT_DTCM1
`ifdef CHUNJUN_SUPPORT_V_EXT
                & (& vbank_idle) // VTCM的所有bank都空闲（可选）
`endif // CHUNJUN_SUPPORT_V_EXT
                ;

//=================================================================================
// Assertion
//=================================================================================

`ifdef CHUNJUN_SUPPORT_DTCM1
`endif // CHUNJUN_SUPPORT_DTCM1
`ifdef CHUNJUN_SUPPORT_V_EXT
`endif // CHUNJUN_SUPPORT_V_EXT

endmodule
`include "chunjun_undefine.sv" 
